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();
同
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);
    }
}
Mar*_*ski 51
这就是我在代码中处理这个问题的方法:
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
    new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
    new MyAsyncTask().execute();
}
并取代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);
        }
    }
}
然后你可以用Utils.execute(mytask)或执行任务,Utils.execute(mytask, params)它将负责并行执行它们.