我目前正在开发Android应用程序,我必须说这一切都非常简单明了。
我对AsyncTask有一个小问题。也许我一直在做错事,但情况就是这样。
我有一个小应用程序,需要从Web加载列表的内容。 我根据假请求开发了所有内容,这一切都很棒。然后我用实际请求更新了代码,得到了'网络主线程错误'。所以我决定切换到AsyncTask。
我想知道我是否可以让AsyncTask执行异步工作,并在其他地方处理结果(我实际上有GUI连接和所有内容)。我认为就可读性和逻辑而言,拥有处理Activity中接口的所有代码更有意义,但是我怎么能让Activity知道任务何时完成?
我写了这些简单的类和接口(并且它可以工作)但是我想知道你是否这是一件好事还是有更好的方法来做到这一点。
所以,这是代码:
public interface AsyncDelegate {
public void executionFinished(LazyLoaderWithDelegate lazyLoaderWithDelegate);
}
这是一个简单的界面。目的是让Activity实现它并处理'executionFinished'方法。像听众一样。
import android.os.AsyncTask;
public class LazyLoaderWithDelegate<Params, Progress, Result> extends AsyncTask<Params, Progress, Result>{
AsyncDelegate delegate;
Result result;
public LazyLoaderWithDelegate(AsyncDelegate delegate){
this.delegate = delegate;
}
@Override
protected Result doInBackground(Object... params) {
//This will be Overridden again from the subclasses anyway.
return null;
}
@Override
protected void onPostExecute(Result r){
this.result = r;
delegate.executionFinished(this);
}
public Result getResult(){
return result;
}
}
这个类基本上给出了一个骨架结构,用于在任务完成时通知代理。
这就是全部。以下是使用此类的示例:
public class LazyVideoLoader extends LazyLoaderWithDelegate<Void, Void, List<List<Video>>>{
public LazyVideoLoader(AsyncDelegate delegate) {
super(delegate);
}
@Override
protected List<Video> doInBackground(Void ...params) {
return ServerInterface.getVideos();
}
}
public class MainActivity extends Activity implements AsyncDelegate {
private LazyVideoLoader videoLoader;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
* Set up the lazy loaders
*/
videoLoader = new LazyVideoLoader(this);
videoLoader.execute();
}
@Override
public void executionFinished(LazyLoaderWithDelegate task) {
if(task == videoLoader){
List<Video> result = videoLoader.getResult();
//Do whatever you need...
}
}
答案 0 :(得分:3)
您在onPostExecute
上运行的所有内容都在UI线程中。此外,只需在onProgressUpdate
上通过调用publishProgress
上的doInBackground
完成工作的某个部分,就可以在UI线程上运行代码。
有关详细信息,请参阅this。它包含您需要了解的有关AsyncTask
的所有信息。
答案 1 :(得分:1)
如果我理解这是正确的,你有一个单独的类,它运行AsyncTask。如果任务完成,则回调使用的接口通知活动。如果您在组件中考虑使代码更加模块化,这是很好的。
最常见的做法是使用AsyncTask作为Activity中的内部类。如果你只是想下载相对较小尺寸的图片或类似的东西,这是首选方式。因为您可以访问内部类中的所有字段,这比在构造函数/接口中传递它们更容易。
为了便于阅读,请不要在额外的类中使用AsyncTask。如果你必须用不同的方法对结果做一些公平的计算/修改,你的方式就可以了。