Android上多线程处理程序的最佳实践是什么?

4

我有一个应用程序,使用了几个HTTP请求,例如:

  • 获取会话ID

  • 获取一些位置数据

  • 获取现有类别

  • (...)等等

我创建了一个HTTPRequestHandler,基本上管理每个请求的所有AsynTasks...这很好用,但我的问题是,我不知道如何有效地管理不同的AsynTasks。例如,在开始GetSomeLocationData Task之前,您需要获取SessionId Task

因此,在我的HTTPRequestHandler中,我有一个队列,启动依赖的AsyncTasks,例如:

private void startSessionIdTask(...) {
    //...
    GetSessionIdTask mGetSessionIdTask = new GetSessionIdTask(this);
    mGetSessionIdTask.execute(url);
}

//and from the postExecute() in GetSessionIdTask I call
public void setSessionId(int mSessionId) {
    mDataHelper.setmSessionId(mSessionId); //set id


    String url = API_URL + API_GET_FAVORITES + URL_VARIABLE;

    List<NameValuePair> params = new LinkedList<NameValuePair>();
    params.add(new BasicNameValuePair("session_id", getSessionId()));
    String paramString = URLEncodedUtils.format(params, "utf-8");
    url += paramString;

    //and finally start another Tasks (and so one...)
    GetLocationsTask mGetLocationsTask = new GetLocationsTask(this);
    mGetSessionIdTask.execute(url);

}

然而,这种方法可以正常工作,但问题在于(取决于连接),此队列需要时间,用户可以启动其他AsynTasks,但由于某些最初的数据尚未加载,它们会失败。
我可以设置一些布尔值,如isSessionIdLoaded,或者为用户阻止UI,但我想知道是否有更好的解决方案?
所以我的问题是:是否有一种将asyntasks放入某种队列(ArrayList、Map等)中并按顺序执行的方法?
3个回答

1
自 Android 3+ 版本开始,AsyncTasks 将在 AsyncTask.SERIAL_EXECUTOR 上串行执行。因此,默认情况下,如果启动了两个 AsyncTasks。
task1.execute();
task2.execute();

如果要执行任务2,必须等待任务1完成(只需查看AsyncTask.SERIAL_EXECUTOR的SDK实现)。如果由于任何原因任务1永远不会完成,则任务2将永远不会开始,并且您的应用程序将死锁。

如果要使用自己独立于默认SERIAL_EXECUTOR的队列,请使用

public final AsyncTask<Params, Progress, Result> executeOnExecutor (Executor exec, Params... params)

请提供自己的执行器(也称线程池)。对于一个项目,我复制了SERIAL_EXECUTOR实现以拥有2个串行队列。

对于Android 2.3到1.6,所有任务默认都是并行的,类似于在Android 3+中调用:

task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,null);

不幸的是,在Android 2.3及以下版本中,您无法指定任务/线程将在哪个执行程序上运行的选项。因此,如果您想要按顺序完成它,您必须自己实现,通过在onPostExecute()中显式地调用task1完成后才调用task2。当然,这个概念可以推广到使用任务队列,前一个任务完成时将调用下一个任务(串行工作队列)。对于此,您将找到大量的文献和模式。


0
我不太确定你在问什么,但如果你只想要一种将可运行对象排队以按顺序在后台线程中执行的方法,那么 Executors.newSingleThreadExecutor() 可能就是你要找的。这可能比它需要的更复杂,但你可以通过谷歌轻松地找到示例和教程。

0

AsyncTask在Android 3+上的执行是串行的。 - Patrick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接