14

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

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

但是我注意到,当使用独立文件时,我无法运行runOnUIThread(),因为它属于Activity该类,所以我将如何能够在扩展而不是扩展的独立AsyncTask(MyAsyncTask.java) 中使用此方法。AsyncTaskActivity

4

4 回答 4

15

那完全没问题。我经常这样做,但这取决于你如何使用它。如果它可以被其他人使用,Activities那么我给它自己的类或共享类。但如果它是出于单一目的,那么我会将其设为MainActivity.

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

我不知道你在做什么,但我不确定你需要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();
于 2013-03-14T12:59:36.650 回答
8

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

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

您可以在 AsyncTask 中创建一个接口,以将 AsyncTask 的响应发送到您的活动,如下所示,并在需要时调用您的侦听器方法。我称之为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();

这可能是你想要的东西!

于 2013-03-14T13:05:00.197 回答
2

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

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

一般来说,您应该尽可能地封装您的 AsyncTask,以便您可以从代码中的任何其他点重用它们。

于 2013-03-14T13:00:10.223 回答
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
于 2013-03-14T13:01:45.337 回答