1

我目前正在开始开发 Android 应用程序,我必须说这一切都非常简单明了。

我有一个关于 AsyncTask 的小问题。也许我做错了什么,但情况就是这样。

我有一个需要从网络加载列表内容的小应用程序。我根据虚假请求开发了所有东西,结果都很棒。然后我用实际请求更新了代码并得到了“主线程错误网络”。所以我决定切换到 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...
        }

}
4

2 回答 2

3

您运行的所有内容onPostExecute都在 UI 线程中。onProgressUpdate您也可以在 UI 线程上运行代码,只要通过调用publishProgresson完成某部分工作即可doInBackground

请参阅以获取更多信息。它有你需要知道的一切AsyncTask

于 2013-07-01T14:21:57.760 回答
1

如果我理解正确,您有一个单独的类,它运行一个 AsyncTask。如果任务完成,作为回调使用的接口通知 Activity。如果您在组件中考虑使代码更加模块化,这很好。

最常见的做法是使用 AsyncTask 作为 Activity 中的内部类。如果您只想下载图片或类似尺寸相对较小的东西,这是首选方式。因为您可以访问内部类中的所有字段,这比在构造函数/接口中传递它们更容易。

不要为了可读性而在额外的类中使用 AsyncTask。如果您必须使用不同的方法对结果进行一些公平的计算/修改,那么您的方式是可以的。

于 2013-07-01T14:44:22.440 回答