很久没写博客了,说实话,我也真是懒,但是久来久之如果你不写博客的话,那么你之前的知道的东西,可能就忘光了,我发现在你找工作的时候,付出的代价是非常的大的,所以我决定下定决心,重拾文笔,来记录自己的学习历程,我也希望大家不要懒,多写写博客,或者使用印象笔记等之类的软件来记笔记。好了,废话不多说,我们今天就来说说主题吧,如题所示,大家就应该知道我想要说什么了,至于为什么要说这个,是因为在面试中,这个AsyncTask的原理几乎都会问,其实,这个在Android中用的也是比较多的,在Android中也是比较经典的。那么AsyncTask的优缺点有以下这么几个:
使用的优点:
简单,快捷
过程可控
使用的缺点:
在使用多个异步操作和并需要进行UI变更时,就变得复杂起来.
开启源码之旅 :
其实AsyncTask的原理就是Handler+Thread,在我们使用AsyncTask一般会重写以下这么几个核心方法:
new AsyncTask(){
@Override
protected void onPreExecute() {//在异步任务之前会调用,可以做一些准备工作,比如dialog的弹出之类的
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Object[] values) {
//这个根据方法签名就能知道,他是用来更新进度条的,也就是说,后台有数据更新的时候,回调用
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Object o) {//这个是,异步任务执行完之后会被调用,将结果返回
super.onPostExecute(o);
}
@Override
protected Object doInBackground(Object[] params) {//这个是在子线程中执行的,用来执行耗时人物,这里面的可以你的网络逻辑之类等
return null;
}
}.execute(null);
通过上面几个核心方法的介绍,下面我们就来真正进入到AsyncTask内部看看,首先我们来看看异步任务的构造方法:
public AsyncTask() {
//这里我以罗马数字来代替他们分别执行的步骤,根据我的步骤来
//1.这个是一个CallAble类型的,我们去看看这个到底是什么,请看2.
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);//标记,用来屏蔽FutureTask中的done方法,至于为什么要弄一个falg,那是因为步骤6中set()方法,又会重新通过FutureTask里的done()方法,最终调用的postResult()方法再次把结果通过handler处理一遍,这样就不好了,所以弄了这么一个flag
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);//设置了线程优先级
//noinspection unchecked
Result result = doInBackground(mParams);//看到没有,这里调用donInBackground方法,这个是在子线程中执行的
Binder.flushPendingCommands();
return postResult(result);//这个方法我们待会看一下里面的实现,其实他就是把结果通过Handler来处理,最后调用onPostExecute,将结果传回主线程中,我们继续看这个方法的实现,请看步骤7.
}
};
//4.这是一个FutureTask,其实他就是一个Runnable类型,我们看,在这里他把一个mWorker实例传给了FutureTask构造方法了。
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
try {
postResultIfNotInvoked(get());
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occurred while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
//5.执行execute方法,看这个作了什么操作:
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
//....省略了
onPreExecute();//这个方法是不是很熟悉,我们之前介绍过了
mWorker.mParams = params;//将你传来的参数赋值给步骤2中的成员变量mParams,他是一个数组,因为可变参数嘛,对不对。
exec.execute(mFuture);//好了,开始执行了,将这个mFuture对象(Runnable类型),会通过execute方法来处理。
return this;
}
//6.run方法的实现,主要的实现都是在这里的
public void run() {
//......
try {
Callable<V> c = callable;//我们之前传进来了一个callable实例
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();//在这里会调用call()方法。我们看看步骤1中,子类的实现
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)//这里为true时,将会执行done()方法,这里就不贴代码了,自己可以去源码
set(result);
}
}.......
}
//2.发现它实现了一个Callable接口,那么这个Call又是什么东西呢?我们看一下步骤3.
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
//3.我们知道线程都是运行都是没有返回值的,那么后来在Java1.5版本对线程作了改进,就是这个,让他有返回值了。好,接着我们第4步。
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
//7.postReust方法的具体实现:
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
//我们是不是,这里是不是通过Handler拿到一个消息,然后发送,我们继续看步骤8,看他具体怎么处理的
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
//8.handlerMessage消息处理:
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]);//看看,拿到结果,那么这个mTask是什么呢?他就是一个AsyncTask的一个实例,调用finish方法,然后没看看这里怎么实现的额.步骤9.
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
//9.finish()方法的具体实现,这里其实就是调用了onPostExecute
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);//看到没有,将结果返回了,是不是,到这里,它的原理就基本结束了
}
mStatus = Status.FINISHED;
}
结束语:
今天的分析就到这里,可能有人看不太懂,但是有一定经验都能看的懂,由于很久没写博客了,语法表达上也退化了,由于水平有限,如有不好的地方,欢迎大家拍砖、吐槽,我会虚心接受。转载请注明出去,谢谢