【问题标题】:Should I use AsyncTask class inside the MainActivity extending Activity?我应该在 MainActivity 扩展 Activity 中使用 AsyncTask 类吗?
【发布时间】:2013-03-14 12:56:19
【问题描述】:

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

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

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

【问题讨论】:

  • 为什么要从 AsyncTask 调用 runOnUIThread?
  • 要更改TextViews,它们不能从其他线程更改。
  • 您可以在 onPostExecute 和 onPreExecute 中更新 UI
  • 我已经编辑了我的答案。你可以通过我用代码编写的方式更新你的文本视图。希望对你有帮助!
  • 使用 onPreExecute() 、 onProgressUpdate() 和 onPostExecute() 来使用 Activity 方法。 onProgressUpdate() 用于通知进度。取决于你。 Best AsyncTask tutorial

标签: android android-asynctask


【解决方案1】:

这完全没问题。我经常这样做,但这取决于你如何使用它。如果它可以被其他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();

【讨论】:

  • 谢谢你的回答我喜欢它,问题是如果它是一个独立的文件,runOnUIThread() 不能运行,我将不得不使用它一个内部类,这是我不想要的,因为我将在 3 个活动中使用同一个类,并且我不会将 AsyncTask 的整个代码放在每个活动中
  • 您不必使用内部类。将活动的引用作为构造函数中的参数传递(就像 codeMagic 所描述的那样)。然后使用activity的引用调用runOnUIThread()方法
  • 如果您需要,我添加了一个小示例。好的,很好,我很高兴它对你有用:)
  • 非常感谢这个例子!
  • 对不起!那是错误的! :D
【解决方案2】:

通常,我们将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();

这可以是你想要的东西!

【讨论】:

  • 那我该如何更改视图呢?如果它是一个独立的类,我无法运行 runOnUIThread()。
  • 你为什么使用runOnUIThread?你对它有什么要求?
  • 我读到您的评论是,您需要在完成 AsyncTask 后在调用者活动中更改 textview 内容?我的理解正确吗?
  • 欢迎提出任何问题,让我知道它是否对您有用
  • 非常感谢您抽出宝贵时间提供帮助。我今晚会试试这个,非常感谢一次又一次,我会尽快回复你!
【解决方案3】:

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

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

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

【讨论】:

  • 是的,这就是为什么我想为它制作一个独立的文件,这样我不仅可以将它用于一个目的,还可以用于多种目的
【解决方案4】:

是的。您可以在MainActivity.java 中创建AsyncTask class

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

【讨论】:

  • 问题是我不想将它用作内部类。我想将它用作一个单独的类。
猜你喜欢
  • 2018-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多