Android小知识-一分钟看完AsyncTask

作者: 爱读书的顾先生 | 来源:发表于2018-10-10 10:11 被阅读14次

使用方式

public final AsyncTask<Params, Progress, Result> execute(Params... params)

Params表示传入的参数,Progress表示当前的进度,Result表示当任务执行完毕后需要返回的结果。

在使用AsyncTask时,需要重写它的几个方法,其中doInBackground(Params… params)方法必须实现,该方法用于执行异步任务,参数params表示异步任务的输入参数,在这个方法中可以通过publishProgress方法来更新任务进度,publishProgress方法会调用onProgressUpdate方法,改方法在主线程中执行;如果需要在执行异步之前做一些初始化操作,比如显示一个进度条,可以重写它的onPreExecute方法,这个方法执行在主线程;当doInBackground方法执行完毕,如果需要异步任务数据返回给主线程,可以重写onPostExecute(Result result)方法,这个方法在主线程中执行,参数result是后台返回的值,也就是doInBackground方法返回的值。

原理

AsyncTask是一个封装了线程池和Handler的异步框架,本质上来说就是一个静态的线程池,AsyncTask派生出的子类可以实现不同的异步任务,这些任务都是提交到静态的线程池中执行。

线程池中的工作线程执行doInBackground(mParams)方法执行异步任务。

    @WorkerThread
    protected abstract Result doInBackground(Params... params);

当任务状态改变之后,工作线程会向UI线程发送消息,AsyncTask内部的InternalHandler响应这些消息,并调用相关回调函数。

    @WorkerThread
    protected final void publishProgress(Progress... values) {
        if (!isCancelled()) {
        //获取InternalHandler并发送消息刷新数据
            getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
                    new AsyncTaskResult<Progress>(this, values)).sendToTarget();
        }
    }

    private static class InternalHandler extends Handler {
        public InternalHandler(Looper looper) {
            super(looper);
        }

        @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:
                //通知UI线程更新数据
                    result.mTask.onProgressUpdate(result.mData);
                    break;
            }
        }
    }

注意事项

内存泄漏

非静态内部类AsyncTask会持有外部类Activity的引用,当Activity被回收时,如果AsyncTask内部在做一些耗时操作,这时由于AsyncTask持有了这个activity的引用,导致无法被释放,导致内存泄漏。

创建一个静态内部类AsyncTask+弱引用WeakReference,在activity的onDestroy中调用AsyncTask的cancel方法。

生命周期

AsyncTask并不会随着Activity销毁而销毁。在activity的onDestroy中调用AsyncTask的cancel方法。

结果丢失

在屏幕旋转,或后台activity由于内存不足,AsyncTask持有的当前activity引用是无效的,这时调用AsyncTask的onPostExecute方法去更新界面是不会生效的。

并行或串行

AsyncTask在Android 1.6之前是串行任务,在Android 1.6时AsyncTask采用线程池处理并行任务,又在Android 3.0开始采用一个线程串行执行任务。

扫码_搜索联合传播样式-标准色版.png

Android、Java、Python、Go、PHP、IOS、C++、HTML等等技术文章,更有各种书籍推荐和程序员资讯,快来加入我们吧!关注技术共享笔记。

838794-506ddad529df4cd4.webp.jpg

搜索微信“顾林海”公众号,定期推送优质文章。

相关文章

网友评论

    本文标题:Android小知识-一分钟看完AsyncTask

    本文链接:https://www.haomeiwen.com/subject/qptpaftx.html