Add*_*dev 28 multithreading android thread-safety android-asynctask
我有2个ASyncTasks,一个从httpPost检索一个值,另一个更新UI的一些元素(包括listview).问题是,由于两个ASyncTasks共享相同的后台线程,如果网络操作首先启动并且运行缓慢(由于网络连接不良).其他背景线程花费太多时间使应用程序不负责任.
由于两个ASyncTasks都是独立的,因此等待另一个非常愚蠢.这将是更合乎逻辑的asynctasks不同的类使用不同的线程,我错了吗?
阅读ASyncTask文档.谈谈使用 executeOnExecutor(),但是如何在低于11的API级别解决这个问题呢?
这是一个重现"问题"的小例子
new Task1().execute();
new Task2().execute();
Run Code Online (Sandbox Code Playgroud)
同
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);
}
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*ski 51
这就是我在代码中处理这个问题的方法:
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
new MyAsyncTask().execute();
}
Run Code Online (Sandbox Code Playgroud)
并取代MyAsyncTask与你Task1和Task2分别.在的AsyncTask根本上改变出现在蜂窝(见Android的SDK文档此节中的"执行命令"),所以在这之前,你启动它像往常一样,为HC及以上,使用executeOnExecutor(),如果你不喜欢新的行为(没有人做,我认为)
稍微更通用的方法是将两个辅助方法放在实用程序类中,如下所示:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以用Utils.execute(mytask)或执行任务,Utils.execute(mytask, params)它将负责并行执行它们.