Asynctask的开发精要

生命周期方法

注意区分哪些方法运行在UI线程, 哪些方法运行在worker thread.

asynctask.jpg
使用Asynctask的目的

使用场景: 在worker thread中执行耗时任务,并将任务的结果用于更新UI.

如果只是需要在一个worker thread中执行耗时操作,
没有更新UI的需要, 就没必要去使用Asynctask, 直接new Thread(runnable).start()就好了.
但在项目中, 经常能看到乱用Asynctask的地方,
比如创建快捷方式的代码, ShortCutUtil.java createHaosouShortCut(), 明明构造一个intent, 通过context.sendBroadcast(intent)就可以通知桌面创建快捷方式的图标, 但非要使用一个Asynctask去执行, 这样使用Asynctask就是不当的.

调用execute()和executeOnExecutor()的区别

一个进程中的多个Asynctask对象的执行是被Asynctask类统一管理的.
调用execute(), 一个进程中的多个Asynctask对象在Android 3.0以上串行的执行任务, 在Android 3.0以下是并行的执行任务. 如果需要在Android 3.0以上并行的执行多个Asynctask对象的任务, 需要调用Android 3.0以上新加的API,executeOnExecutor().
所以, 项目统一提供了一个ParallelAsyncTask类, 给了一个parallelExecute() API, 方便项目中正确使用Asynctask类, 让一个进程中的多个Asynctask对象并行的执行.

public abstract class ParallelAsyncTask<Params, Progress, Result> extends
        AsyncTask<Params, Progress, Result> {
    public final ParallelAsyncTask<Params, Progress, Result> parallelExecute(Params... params) {
        try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                return (ParallelAsyncTask<Params, Progress, Result>) super.executeOnExecutor(
                        THREAD_POOL_EXECUTOR, params);
            } else {
                return (ParallelAsyncTask<Params, Progress, Result>) super.execute(params);
            }
        } catch (Throwable e) {
            e.printStackTrace();
            return this;
        }
    }
}
使用细节
1. 创建Asynctask对象, 以及调用execute()或executeOnExecutor()的操作都要在UI线程

2. 停止Asynctask, 调用cancel(boolean mayInterruptIfRunning) API, mayInterruptIfRunning参数为true.

3. 一个Asynctask对象只能执行一次, 即只能对它调用一次execute()或executeOnExecutor(), 对同一个对象再次调用执行则会报运行时异常.
底层实现

Asynctask有一个static的线程池对象, 用于执行一个进程中的所有Asynctask对象.

public static final Executor THREAD_POOL_EXECUTOR
            = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                    TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

还有一个Handler对象, 用于在handleMessage(Message msg)中, 在UI线程调用onProgressUpdate(Progress... values)和onPostExecute(Result result)

private static InternalHandler sHandler;
private static class InternalHandler extends Handler {
    public InternalHandler() {
        super(Looper.getMainLooper());
    }

    @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
    @Override
    public void handleMessage(Message msg) {
        AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
        switch (msg.what) {
        case MESSAGE_POST_RESULT:
            // There is only one result
            result.mTask.finish(result.mData[0]);
            break;
        case MESSAGE_POST_PROGRESS:
            result.mTask.onProgressUpdate(result.mData);
            break;
        }
    }
}

-----DONE.-----

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容