4

我有一个应用程序,它使用了几个HTTPRequests例如

  • 获取会话 ID

  • 获取一些位置数据

  • 获取现有类别

  • (...) 还有更多

我创建了一个HTTPRequestHandler,它基本上管理AsynTasks每个请求的所有内容...这很好用,但我的问题是,我不知道管理不同的AsynTasks. 例如,您需要先获取SessionId Task才能启动GetSomeLocationData 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,但我想知道,是否有更好的解决方案?!

所以我的问题是:有没有办法将异步任务放入某种队列(ArrayList,Map..)中,将连续执行?

4

3 回答 3

1

从 Android 3+ 开始,AsyncTasks 将在AsyncTask.SERIAL_EXECUTOR. 因此,默认情况下,如果您启动 2 个 AsyncTasks

task1.execute();
task2.execute();

Task2 只有在 task1 完成后才会执行(只需检查 sdk 的实现AsyncTask.SERIAL_EXECUTOR)。这可以推到这一点,如果 task1 出于任何原因永远不会完成, task2 将永远不会启动并且您已经死锁了您的应用程序。

如果您希望自己的队列独立于默认的 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 及更低版本中,您无法指定任务/线程将在其上运行的执行程序。因此,如果您想连续完成它,您必须自己实现它,仅在 task1 明确完成后调用 task2 onPostExecute()。这个概念当然可以被推到使用一个任务队列,前一个任务将在完成时调用下一个任务(=串行工作队列)。为此,您会发现大量的文献和模式。

于 2013-06-26T21:53:04.003 回答
0

我不完全确定你在问什么,但如果你只是想要一种方法来排队 Runnables 以按顺序在后台线程中执行,那么Executors.newSingleThreadExecutor()可能就是你要找的。它比它可能需要的更复杂,但您可以通过 google 轻松找到示例和教程。

于 2013-05-06T20:31:24.540 回答
0

如果您需要顺序执行,我建议您切换到IntentService而不是使用AsyncTask. 请参阅文档:http: //developer.android.com/reference/android/app/IntentService.html

于 2013-06-26T19:37:44.987 回答