我有2个ASyncTasks,一个从httpPost检索一个值,另一个更新UI的一些元素(包括listview)。 问题是,由于两个ASyncTasks共享相同的后台线程,如果网络操作首先启动并且运行缓慢(由于网络连接不良)。其他背景线程花费了太多时间使应用程序不负责任。
由于两个ASyncTasks都是独立的,因此非常愚蠢地等待另一个。这将是更合乎逻辑的asynctasks不同的类使用不同的线程,我错了吗?
阅读ASyncTask文档。谈谈使用 executeOnExecutor(),但我怎样才能在低于11的API级别解决这个问题?
这是一个重现“问题”的小例子
new Task1().execute();
new Task2().execute();
使用
public class Task1 extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
GLog.e("doInBackground start 1");
SystemClock.sleep(9000);
GLog.e("doInBackground end 1");
return null;
}
@Override
protected void onPreExecute() {
GLog.e("onPreExecute 1");
super.onPreExecute();
}
@Override
protected void onPostExecute(Void result) {
GLog.e("onPostExecute 1");
super.onPostExecute(result);
}
}
public class Task2 extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
GLog.e("onPreExecute 2");
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
GLog.e("doInBackground start 2");
SystemClock.sleep(9000);
GLog.e("doInBackground end 2");
return null;
}
@Override
protected void onPostExecute(Void result) {
GLog.e("onPostExecute 2");
super.onPostExecute(result);
}
}
答案 0 :(得分:49)
这就是我在代码中处理这个问题的方法:
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new MyAsyncTask().execute();
}
分别用您的MyAsyncTask
和Task1
替换Task2
。基本上AsyncTask中的更改出现在Honeycomb中(请参阅“执行顺序”部分中的Android SDK文档here),因此在此之前,您可以像往常一样启动它,对于HC和up,如果你这样做,请使用executeOnExecutor()
不像新的行为(我认为没有人)
答案 1 :(得分:7)
稍微更通用的方法是将两个辅助方法放在实用程序类中,如下所示:
class Utils {
@SuppressLint("NewApi")
public static <P, T extends AsyncTask<P, ?, ?>> void execute(T task, P... params) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
} else {
task.execute(params);
}
}
}
然后,您可以使用Utils.execute(mytask)
或Utils.execute(mytask, params)
执行任务,它将负责并行执行它们。
答案 2 :(得分:1)
问题是每个AsyncTask都运行在编码到API中的相同ThreadPoolExecutor中。此ThreadPoolExecutor可以根据您的Android版本创建不同数量的WorkerThread。我不记得数字版本,但想法是在较旧的Android版本中它是1 WorkerThread。然后在更高版本中将其更新为5。最近再次回到了1。这就是您的AsyncTasks被阻止的原因。它们在同一个WorkerThread上运行,因此它们按顺序执行。尝试使用带有THREAD_POOL_EXECUTOR的executeOnExecutor来实现真正的并行执行。但是,您只能在API 11之后使用它。