java Android 开发:在单独的类文件中有一个 AsyncTask
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15487807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android Development: Having an AsyncTask in a separate class file
提问by cosmicsafari
I have been playing around with various examples trying to familiarize myself with AsyncTask. So far all the examples I have seen have had the AsyncTask included into the onCreate method of the main activity. Which I don't like very much, so I was wanting to see how hard it would be to separate it into its own class. So far I have this:
我一直在玩各种示例,试图让自己熟悉 AsyncTask。到目前为止,我看到的所有示例都将 AsyncTask 包含在主活动的 onCreate 方法中。我不太喜欢它,所以我想看看将它分成自己的类有多难。到目前为止,我有这个:
the main activity
的主要活动
package com.example.asynctaskactivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.example.asynctaskactivity.ShowDialogAsyncTask;
public class AsyncTaskActivity extends Activity {
Button btn_start;
ProgressBar progressBar;
TextView txt_percentage;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn_start = (Button) findViewById(R.id.btn_start);
progressBar = (ProgressBar) findViewById(R.id.progress);
txt_percentage= (TextView) findViewById(R.id.txt_percentage);
Log.v("onCreate","Attempt set up button OnClickListener");
btn_start.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v) {
btn_start.setEnabled(false);
new ShowDialogAsyncTask().execute();
}
});
Log.v("onCreate","Success!");
}
}
the new seperate AsyncTask class
新的独立AsyncTask 类
package com.example.asynctaskactivity;
import android.os.AsyncTask;
import android.os.SystemClock;
import android.util.Log;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class ShowDialogAsyncTask extends AsyncTask<Void, Integer, Void>{
int progress_status;
@Override
protected void onPreExecute() {
// update the UI immediately after the task is executed
Log.v("onPreExecute","1");
super.onPreExecute();
Log.v("onPreExecute","2");
//Toast.makeText(AsyncTaskActivity.this,"Invoke onPreExecute()", Toast.LENGTH_SHORT).show();
progress_status = 0;
Log.v("onPreExecute","3");
txt_percentage.setText("downloading 0%");
Log.v("onPreExecute","4");
}
@Override
protected Void doInBackground(Void... params) {
Log.v("doInBackground","1");
while(progress_status<100){
progress_status += 2;
publishProgress(progress_status);
SystemClock.sleep(300);
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressBar.setProgress(values[0]);
txt_percentage.setText("downloading " +values[0]+"%");
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//Toast.makeText(AsyncTaskActivity.this,"Invoke onPostExecute()", Toast.LENGTH_SHORT).show();
txt_percentage.setText("download complete");
btn_start.setEnabled(true);
}
}
Originally this was all in the main activity, hence the mentions to the elements that the asynctask should in theory update. Obviously at present this is causing runtime errors, which then got me thinking. How can I have the file seperate but still update the UI thread.
最初这一切都在主要活动中,因此提到了 asynctask 理论上应该更新的元素。显然,目前这会导致运行时错误,这让我开始思考。如何将文件分开但仍更新 UI 线程。
Sorry if this is a stupid question, quite new to android development and background threads in particular.
对不起,如果这是一个愚蠢的问题,特别是对于 android 开发和后台线程来说,这是一个新问题。
回答by Simon Dorociak
How can I have the file seperate but still update the UI thread.
如何将文件分开但仍更新 UI 线程。
Okey. So at first you know that main advantage of AsyncTask
added in Activity as inner class is that you have direct access to all UI elements and it makes possible pretty "lightweight" UI updates.
好的。因此,首先您知道AsyncTask
将 Activity 添加为内部类的主要优点是您可以直接访问所有 UI 元素,并且可以实现非常“轻量级”的 UI 更新。
But if you decided to make AsyncTask separated from Activity(which also have some benefits e.q. code is more clean and app logic is separated from appearance) class you can:
但是,如果您决定将 AsyncTask 与 Activity 分开(这也有一些好处 eq 代码更干净并且应用程序逻辑与外观分离)类,您可以:
- You can pass UI elements via constructor of class
- You can create various setters
- You can create some interface that will hold callbacks. Look at
Android AsyncTask sending Callbacks to UI
- 您可以通过类的构造函数传递 UI 元素
- 您可以创建各种设置器
- 您可以创建一些接口来保存回调。看着
Android AsyncTask sending Callbacks to UI
This is all what you need i guess.
我猜这就是你所需要的。
回答by nhaarman
Add a callback interface, and let your Activity
implement it.
添加一个回调接口,让你Activity
实现它。
public interface MyAsyncTaskCallback{
public void onAsyncTaskComplete();
}
In the postexecute:
在后执行中:
myAsyncTaskCallback.onAsyncTaskComplete();
In the constructor of your AsyncTask
you could pass the instance of MyAsyncTaskCallback
(your Activity
).
在您的构造函数中,您AsyncTask
可以传递MyAsyncTaskCallback
(your Activity
)的实例。
回答by BrianPlummer
Your best way of handling this is via a Handler. Instantiate one in the activity and override the method handleMessage()
. When you create ShowDialogAsyncTask
class just pass in the handler and maintain a reference to it. On postExecute
you can construct a message and send it via the handler method sendMessage()
.
处理此问题的最佳方法是通过 Handler。在活动中实例化一个并覆盖方法handleMessage()
。当您创建ShowDialogAsyncTask
类时,只需传入处理程序并维护对它的引用。在postExecute
你可以构造一个消息,并通过处理方法发送sendMessage()
。
A previous answer mentioned using an interface and a callback paradigm. This will work, however, there is a chance that the activity can be destroyed and won't be present when the postExecute
method is executed so you would need to test for this.
之前的答案提到使用接口和回调范例。这将起作用,但是,活动有可能被销毁并且在postExecute
执行方法时不存在,因此您需要对此进行测试。