是否可以将AsyncTask类放在Activity类中?

时间:2016-05-25 16:24:46

标签: android android-asynctask

在Activity类中编写AsyncTask类是否可以?或者我应该为此创建另一个文件?但是,在这种情况下,我无法操纵UI,或从AsyncTask更新它。那么,如果我要为AsyncTask创建另一个文件,那我怎么能更新Activity类中的UI呢?提前致谢!

4 个答案:

答案 0 :(得分:2)

  

在Activity类中编写AsyncTask类是否可以?

是的,没关系,但不是一个好习惯。这是一个干净的编码问题,将视图控制器分开。它还可能导致内存泄漏问题。您可以将Activity的引用传递给AsyncTask,但应该只是一个弱引用。

  

我无法操作UI,或者从AsyncTask更新它。所以,如果我是   为AsyncTask创建另一个文件,然后我如何更新UI   活动课?

在这种情况下,有很多方法可以更新UI。您可以使用BroadcastReceiverHandlerInterface

我建议您使用Interface,因为它是最简单的,我认为是最合适的。{/ p>

以下是一个示例:

您为AsyncTask创建一个新文件。你编写了一个新的子类AsyncTask。

public class DownloadTask extends AsyncTask<String, Float, Long>
{
    public DownloadTaskListener mListener;

    public interface DownloadTaskListener
    {
        public void onDownloadFinish();
        public void onDownloadProgress(float progress);
    }

    @Override
    protected Long doInBackground(String... arg0) 
    {
        //start downloading

        return 0L; //return download size
    }

    protected void onProgressUpdate(Float... progress) 
    {
        if(mListener != null)
        {
            mListener.onDownloadProgress(progress[0]);
        }
    }

    protected void onPostExecute(Long result) 
    {
        if(mListener != null)
        {
            mListener.onDownloadFinish();
        }
    }
}

正如您在此处所见,您可以使用界面的这些方法来通知UI的更新。

public interface DownloadTaskListener
{
    public void onDownloadFinish();
    public void onDownloadProgress(float progress);
}

在您的MainActivity中,您必须实现该接口,以便回调起作用:

public class MainActivity extends Activity implements DownloadTaskListener
{
    DownloadTask download = new DownloadTask();

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        download.mListener = this;
        download.execute("Download URL");
    }

    @Override
    public void onDownloadFinish() 
    {
        MainActivity.this.runOnUiThread(new Runnable() 
        {
            public void run() 
            {
                //updates to UI here.
            }
        });
    }

    @Override
    public void onDownloadProgress(float progress) 
    {
        MainActivity.this.runOnUiThread(new Runnable() 
        {
            public void run() 
            {
                //updates to UI here.
            }
        });
    }
}

看看这一行:

download.mListener = this;

您只需传递Activity的引用(实现接口),以便AsyncTask可以调用Activity的接口方法,以便您更新Activity。

还要注意AsyncTask是一个Thread。更新UI的某些更改时,应始终在主线程或UI线程中执行此更改。检查这部分:

MainActivity.this.runOnUiThread(new Runnable() 
            {
                public void run() 
                {

                }
            });

对不起,不是专业的解释员,但我希望我能为你清楚说明。 :)

答案 1 :(得分:0)

是的,没关系,但在我的情况下,我使用另一个文件。

在onPostExecute方法中,您可以使用UI进行intercat:

  1. 您可以将活动/片段传递给AsyncTask,并在onPostExecute中更新您的&#39; UI。

  2. 您可以使用界面(回调)来获得结果 - Android - Jsoup: How to get RESULT from Jsoup.connect("url").get() from AsyncTask

  3. 我更喜欢第二个选项

答案 2 :(得分:0)

你可以这样做。如果将AsyncTask Class放在“活动本身”中,则不会出现问题。

我更喜欢将我的AsyncTask类保存在不同的文件中,而且我与UI交互的方式如下:

  • 使用EventBus
  • onPostExecute
  • 中发布相应的活动
  • 在您的活动中捕获该事件并执行任何需要完成的操作

我认为这是一种更清晰的做事方式。如果你使用 EventBus 一次,你会爱上它。

答案 3 :(得分:0)

一般来说,这不好,因为在软件开发中 人们应该尽量避免耦合。 现在考虑Android框架,imho,UI是UI和背景 流程,服务是另一回事。
就个人而言,我不使用这种方法,因为我不喜欢耦合,加上单元测试将是一个痛苦的屁股。但是,如果有人决定采用这种方法,那么应该考虑一下它究竟是什么:
Q1:你想要哪一堂课?
内部类静态嵌套类

- 内部课程    - 对于内部类,因为类是其封闭类的成员,所以可以访问封闭实例的变量和成员。这里的问题可能是在轮换期间(Activity),活动中的一些变量可能会发生变化。

- 静态嵌套类   - 静态嵌套类的行为类似于外部类,因此无法访问其封闭的类成员和变量。它可以使用的唯一方法是通过对象引用。这种方法基本上告诉你,另一个类和静态嵌套类之间没有区别。


编辑 - 轮换的一些起点

由于上述条件以及Android应该真正处理旋转的事实,我使用以下概念:

//changed from activity to fragment if rotation is considered.
public CustomFragment extends Fragment{

    @Override
    void onCreate(Bundle saveInstance){
        super.onCreate(saveInstance);
        //for avoiding rotation problems
        setRetainInstance(true);
        new CustomAsyncTask(this, callback).execute();
    }

    public Callback callback = new Callback{
       @Override
       public void onSuccess(){
           //do something
       }

      @Override
      public void onFail(){
          //do something
      }

      @Override
      public void onTaskStarted(){
          //start showing the progress dialog
      }

      @Override
      public void onTaskInProgress(Integer value){
          //progress dialog has some method set progress, check it out
      }

   }

   public interface Callback {
      void onSuccess();
      void onFail();
      void onTaskStarted();
      void onTaskInProgress(Integer progress);
  }  
}


//asynctask class

public class CustomAsyncTask extends AsyncTask<Void, Void, Void> {

      private CustomFragment callback;
      public AsyncCallerTickets(CustomFragment _callback){
            this.callback = _callback;
      }  

      @Override
      protected void onPreExecute() {
         super.onPreExecute();
         callback.onTaskStarted();
      }

      @Override

     @Override
     protected void onProgressUpdate(Integer...progress) {
        callback.onTaskInProgress(progress[0]);    
     }      

    protected Void doInBackground(Void... params) {
          //long process
          return null;
     }


     @Override
     protected void onPostExecute(Void result) {
          super.onPostExecute(result);
          //dialog.dismiss();?
          if(result!=null){
              callback.onSucces();
          }
          else{
               callback.onFail();
          }
     }
  }


   通过尽可能地分离事物,可以缓解Android中的旋转疼痛。