Asynctask原理

本文详细解析了Android中的AsyncTask机制,包括其内部实现原理、关键方法的功能及调用流程。介绍了如何通过AsyncTask进行异步任务处理,提高应用程序的响应性和用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AsyncTask 异步任务,主要包含两个关键类:

InternalHandler:消息处理器, 用于处理线程之间消息.

ThreadPoolExecutor:线程池, 用于处理耗时任务



1、onPreExecute(): 在UI线程里面调用,它在这个task执行后会立即调用。我们在这个方法里面通常是用于建立一个任务,比如显示一个等待对话框来通知用户。
2、doInBackground(Params...):这个方法从名字就可以看出,它是运行在后台线程的,在这个方法里面,去做耗时的事情,比如下载访问网络,操作文件等。
这这个方法里面,我们可以调用publishProgress(Progress...)来调用当前任务的进度,调用了这个方法后,对应的onProgressUpdate(Progress...)方法会被调用,
这个方法是运行在UI线程的。
3、onProgressUpdate(Progress...):运行在UI线程,在调用publishProgress()方法之后。这个方法用来在UI上显示任何形式的进度,比如你可以显示一个等待对话框,
也可以显示一个文本形式的log,还可以显示toast对话框。
4、onPostExecute(Result):当task结束后调用,它运行在UI线程。
5、取消一个task,我们可以在任何时候调用cancel(Boolean)来取消一个任务,当调用了cancel()方法后,onCancelled(Object)方法就会被调用,
onPostExecute(Object)方法不会被调用,在doInBackground(Object[])方法中,我们可以用isCancelled()方法来检查任务是否取消。
6、几点规则:
AsyncTask实例必须在UI线程中创建   
execute(Params...)方法必须在UI线程中调用。
不用手动调用onPreExecute(), onPostExecute(), doInBackground(), onProgressUpdate()方法。
一个任务只能被执行一次

------------------------------------

# AsyncTask原理


new AsyncTask<String, String, String>() {

// 2. 运行在主线程中, 做一些准备操作.
public void onPreExecute() {


}


// 3. 运行在子线程中, 做一些耗时的任务.
public String doInBackground(String... params) {
return null;
}


// 4. 运行主线程中, result就是doInBackground方法返回的值. 做一些收尾操作.
public void onPostExecute(String result) {


}
}.execute(String... params); // 1. 开始执行异步任务.


> #### AsyncTask的execute的方法, 代码如下: 


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


        mStatus = Status.RUNNING;


// 调用用户的实现方法, 让用户做一些准备操作. 运行在主线程中.
        onPreExecute();


// 把mWorker中的mParams赋值为用户传递进来的参数.
        mWorker.mParams = params;
// 使用线程池, 执行任务. 这时进入到子线程中.
        sExecutor.execute(mFuture);


        return this;
    }


> #### 查看mWorker的初始化过程, 代码如下:


// AsyncTask构造函数在一开始使用异步任务时, 已经调用.
public AsyncTask() {
        mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                ...
            }
        };


// 1. 把mWorker对象传递给了FutureTask的构造函数
        mFuture = new FutureTask<Result>(mWorker) {
            @Override
            protected void done() {
                ...
            }
        };
    }


// FutureTask类中接收的是Callable的类型, 其实WorkerRunnable类型实现了Callable的类型.
    public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
// 2. 把callable(mWorker)传递给了Sync的构造函数.
        sync = new Sync(callable);
    }


    Sync(Callable<V> callable) {
  // 3. 把接收过来的callable(mWorker)对象赋值给Sync类中的成员变量callable
// 总结: Sync类中的成员变量callable就是AsyncTask中的mWorker对象.
        this.callable = callable;
    }


> #### mFuture对象中的run方法如下:


public void run() {
// 1. 调用了innerRun方法.
        sync.innerRun();
    }


    void innerRun() {
        if (!compareAndSetState(READY, RUNNING))
            return;


        runner = Thread.currentThread();
        if (getState() == RUNNING) { // recheck after setting thread
            V result;
            try {
// 2. 调用了callable(mWorker)的call方法. 获取一个返回结果.
                result = callable.call();
            } catch (Throwable ex) {
                setException(ex);
                return;
            }
// 4. 把结果传递给set方法.
            set(result);
        } else {
            releaseShared(0); // cancel
        }
    }




// 在AsyncTask的构造函数中, mWorker对象初始化时, 已经覆盖了call方法, 代码如下
    public Result call() throws Exception {
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
// 3. 调用了用户实现的doInBackground方法, 去执行一个耗时的任务. 运行在子线程中.
// doInBackground接收的参数就是execute方法接收的参数.
        return doInBackground(mParams);
    }








----------




    protected void set(V v) {
// 5. 继续把参数传递给innerSet方法.
        sync.innerSet(v);
    }


    void innerSet(V v) {
        for (;;) {
            int s = getState();
            if (s == RAN)
                return;
            if (s == CANCELLED) {
                // aggressively release to set runner to null,
                // in case we are racing with a cancel request
                // that will try to interrupt runner
                releaseShared(0);
                return;
            }
            if (compareAndSetState(s, RAN)) {
// 6. 把doInBackground返回的结果赋值给成员变量result
                result = v;
                releaseShared(0);
// 7. 调用FutureTask中的done方法.
                done();
                return;
            }
        }
    }




----------




// 此方法定义在AsyncTask的构造函数中, 初始化mFuture时,已经覆盖了done方法, 代码如下:
@Override
    protected void done() {
        Message message;
        Result result = null;


        try {
// 8. 调用FutureTask中的get方法获取result(doInBackground返回的结果).
            result = get();
        } catch (InterruptedException e) {
            android.util.Log.w(LOG_TAG, e);
        } catch (ExecutionException e) {
            throw new RuntimeException("An error occured while executing doInBackground()",
                    e.getCause());
        } catch (CancellationException e) {
            message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
                    new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
            message.sendToTarget();
            return;
        } catch (Throwable t) {
            throw new RuntimeException("An error occured while executing "
                    + "doInBackground()", t);
        }


// 11. 创建一个消息对象.
// msg.what = MESSAGE_POST_RESULT;
// msg.obj = new AsyncTaskResult<Result>(AsyncTask.this, result);
        message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult<Result>(AsyncTask.this, result));
// 12. 把当前消息使用sHandler发送出去.
        message.sendToTarget();
    }


public V get() throws InterruptedException, ExecutionException {
// 9. 转调innerGet方法.
        return sync.innerGet();
    }


    V innerGet() throws InterruptedException, ExecutionException {
        ...


// 10. 把result(doInBackground的结果)返回回去. result成员变量是在innerSet方法中赋值. 详情看第6步.
        return result;
    }




----------


    private static class InternalHandler extends Handler {
   @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
   @Override
   public void handleMessage(Message msg) {
// 把obj转换成AsyncTaskResult类, 这个类中mTask对象就是当前的AsyncTask对象. mData对象就是doInBackground的返回结果.
       AsyncTaskResult result = (AsyncTaskResult) msg.obj;
       switch (msg.what) {
           case MESSAGE_POST_RESULT:
               // There is only one result
// 13. 调用AsyncTask中的finish方法, 并且把doInBackground的返回结果传递进去.
               result.mTask.finish(result.mData[0]);
               break;
           case MESSAGE_POST_PROGRESS:
               result.mTask.onProgressUpdate(result.mData);
               break;
           case MESSAGE_POST_CANCEL:
               result.mTask.onCancelled();
               break;
       }
   }
}


    private void finish(Result result) {
        if (isCancelled()) result = null;
// 14. 把doInBackground的返回结果传递给用户实现的onPostExecute方法. 运行在主线程中, 用户可以做一些操作界面, 更新界面的操作.
        onPostExecute(result);
        mStatus = Status.FINISHED;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值