ASyncTasks阻止其他人

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与你Task1Task2分别.在的AsyncTask根本上改变出现在蜂窝(见Android的SDK文档节中的"执行命令"),所以在这之前,你启动它像往常一样,为HC及以上,使用executeOnExecutor(),如果你不喜欢新的行为(没有人做,我认为)


Nik*_*kov 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以用Utils.execute(mytask)或执行任务,Utils.execute(mytask, params)它将负责并行执行它们.