我应该在MainActivity扩展Activity中使用AsyncTask类吗?

时间:2013-03-14 12:56:20

标签: android android-asynctask

我想知道是否在运行该线程的主要活动(AsyncTask)中使用了MainActivity.java

例如,我注意到许多教程在使用AsyncTask时在扩展Activity的主类中声明了一个私有类,而不是为.java创建一个独立的AsyncTask文件。 (MyAsyncTask.javaclass

但我注意到当使用独立文件时我无法运行runOnUIThread(),因为它属于Activity类,那么我将如何使用此方法在独立的AsyncTask(MyAsyncTask.java)里面,它扩展了AsyncTask而不是Activity

4 个答案:

答案 0 :(得分:14)

这完全没问题。我经常这样做,但这取决于你如何使用它。如果它可以被其他Activities使用,那么我给它自己的类或共享类。但如果它是出于一个目的,那么我会把它变成MainActivity的内部类。

使其成为内部类的好处是它可以直接访问该类成员变量。如果你把它作为一个单独的类,那么你需要为它创建一个构造函数,如果你需要传递params,如context或其他变量。

我不确切知道你在做什么,但我不确定你需要runOnUiThread()。您可以在AsyncTask文件中创建构造函数,并让它接受context作为参数以及您需要的任何其他内容。然后,您可以更新UI

中的onPostExecute()

示例

public class MyAsyncTask extends AsyncTask{

    private Context context; 

    public MyAsyncTask(Context context) {  // can take other params if needed
        this.context = context;
    }

    // Add your AsyncTask methods and logic
    //you can use your context variable in onPostExecute() to manipulate activity UI
}

然后在MainActivity

中调用它
MyAsyncTask myTask = new MyAsyncTask(this);  //can pass other variables as needed
myTask.execute();

答案 1 :(得分:6)

通常我们将AsyncTask放在同一个类中,以便更清楚地表明它仅由同一个活动使用。

如果你希望AsyncTask被多个活动重用,你可以简单地创建一个独立的类,并通过构造函数传递活动中的参数

您可以在asyncTask中创建接口,以便将asynctask的响应发送到您的活动,如下所示,并在需要时调用lister方法。我称之为onPostExecute()

public class DeckDownloader extends AsyncTask<Void, Void, String> {

    OnDownloadUpdateListener listener;

    public interface OnDownloadUpdateListener {
         public void OnDownloadDeckFinish(String Response);     
    }


    public DeckDownloader(Context ctx, OnDownloadUpdateListener listener) {
         mContext = ctx;
         this.listener = listener;
    }

    @Override
    protected String doInBackground(Void... params) {
         String str = "downloading";
         //your async code goes here
         return str;
    }

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

     @Override
     protected void onPostExecute(String result) {
          if( listener != null ) {
                listener.OnDownloadDeckProgress(result);
          }
     }
}

在您的Activity类中,您需要实现该侦听器并编写代码以在该实现方法中更新textview:

    public class myActivity extends Activity{
          private DeckDownloader.OnDownloadUpdateListener downloadListener;
          TextView txtAsyncResponse;

          @Override
          public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              txtAsyncResponse = (TextView) findViewById(R.id.txtAsyncResponse);


            downloadListener = new DeckDownloader.OnDownloadUpdateListener() {
               @Override
               public void OnDownloadDeckFinish(String Response) {
                    txtAsyncResponse.setText(Response);
               }
            };
    }

您可以在下面编写代码,以便在您的活动中启动AsyncTask,只需按钮点击事件或其他

 DeckDownloader mTask = new DeckDownloader(this.getApplicationContext(), downloadListener);
 mTask.execute();

这可能是你想要的thindg!

答案 2 :(得分:2)

我相信在大多数教程中他们选择最容易理解/阅读的内容,而不是实际上最好的内容。

使用内部类,可以保持Activity的变量可用,这可以更简单。

通常,您应该尽可能地封装AsyncTasks,以便可以从代码中的任何其他位置重复使用它们。

答案 3 :(得分:2)

是。您可以在AsyncTask class

中创建MainActivity.java
public class CategoryListScreen extends Activity {


    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        new loadcategory().execute();
    }

    class loadcategory extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) { }
        protected void onPostExecute(Void param) { }
    } // AsyncTask over
}//main class over