AsyncTask解析

目录:
* 1.AsyncTask介绍
* 2.AsyncTask中提供了四个核心方法
* 3.AsyncTask的注意事项
* 4.AsyncTask实现原理
* 5.AsyncTask执行的串行和并发

AsyncTask介绍:

简介:

AsyncTask是一个轻量级的异步任务类,它可以在线程池中后台执行任务,可以将执行的进度和执行完成之后的结果返回到UI线程中;

AsyncTask是一个抽象的泛型类,其有三个泛型形参,params,progress,result

如下:

public abstract class  AsyncTask<Params,Progress,Result>

三个泛型形参含义分别如下:

//Params : 执行后台任务所需参数的类型
//Progress : 更新进度的类型
//Result : 执行完后台任务后返回结果的类型

AsyncTask中提供了四个核心方法:

onPreExecute(): 在UI线程中执行,用于在异步任务执行之前,在该方法内执行相应的准备任务逻辑

doInBackground(Params… params): 在线程池中执行,该方法用于执行确切的后台任务,任务执行的进度可调用publishProgress()方法来刷新当前的执行进度给UI线程,在publishProgress()会调用onProgressUpdate在UI线程中进行相关的UI界面刷新的逻辑;在该方法执行完成以后还需要返回一个Result结果,返回给onPostExecute方法

onProgressUpdate(Progress… value): 在UI线程中执行,用于更新当前后台任务的执行进度

onPostExcute(Result result): 在UI线程中执行,在后台任务执行完成之后会调用该方法,该方法的形参Result是doInBackground执行完成之后返回的.


AsyncTask中提供了四个核心方法:
  1. AsyncTask类必须要在主线程中加载
  2. AsyncTask对象必须在主线程中调用
  3. AsyncTask的execute方法必须在主线程中调用
  4. 一个AsyncTask对象只能调用一次execute,否则会抛出异常
  5. onPreExecute,doInBackground,onProgressUpdate,onPostExcute等方法不要手动去调用.

AsyncTask实现原理:
public final AsyncTask<Params,Progress,Result> execute(Params...params){

return executeOnExecutor(sDefaultExecutor,params);
}

public final AsyncTask<Params,Progress,Result> executeOnExecutor (Executor
exec,Params...params){
if(mStatus l-Status.PENDING){
switch (mStatus){
case RUNNING:
throw new IllegalStateException("Cannot execute task:"
+"the task is already running.");
case EINISHED:
throw new IllegalStateException("Cannot execute task:"
"the task has already been executed"
"(a task can be executed only once)");

    }
}
mStatus=Status.RUNNING;
onPreExecute();
mWorker.mParams=params;
exec,execute(mFuture);
return this;
}

AsyncTask实现就从其调用execute说起,execute就创建了其对象,而在execute内部调用了executeOnExecutor,executeOnExecutor需要传入两个形参,一个是Excute,一个是Params,在调用中传入了一个sDefaultExecutor,sDefaultExecutor是一个默认创建的线程池,用于排队.
executeOnExecutor内部调用了onPreExecutor函数,完成了异步任务执行前的准备工作,其后将params参数封装成了FutrueTask对象,调用了sDefaultExecutor的execute方法将FutrueTask传入execute中;

public static final Executor SERIAL EXECUTOR new SerlalExecutor();
private statio volatlile Executor sDefaultBxecutor=SERIAL EXECUTOR;
private static class SerialExecutor implementa Executor{
final Arraypeque<Runnable>mraska =new ArrayDeque<Runnable>();
Runnable mActive;
publie aynchronized void execute(final Runnable x){
mrasks.offer (new Runnable()(
public vold run()(
try(
r.run();
1finally{
acheduleNext();
    }
}
});
f(mActive==null){
acheduleNext();
}
}
protectod synchronized void scheduleNext({
if((mActive=mrasks,poll())i=null){

    THREAD_POOL_EXECUTOR.execute(mActive);
      }
    }
}

而在execute中,将需要执行的后台任务加入到了一个双端队列中,队列接收的是Runnable类型,在匿名内部类方式新创建的Runnable内部调用了FutrueTask的run方法,而后调用了scheduleNext函数,而在scheduleNext方法中将需要执行的任务传递到了THREAD_POOL_EXECUTOR线程池中进行执行操作,而在此处调用scheduleNext方法,当run方法执行完后,就可直接去执行下一个后台任务.而在run方法后,判断mActive为空说明当前没有执行的任务,又再一次调用了scheduleNext,在此处调用是为了前面刚新投递入一个新的任务,当前没有在执行任务就直接去执行新的任务.

在AsyncTask内部有两个线程池sDefaultExecutor(用于排队队列)和THREAD_POOL_EXECUTOR(用于执行后台任务),以及一个Handler(internalHandler,将执行任务的环境由线程池切换为主线程)

mWorker=new WorkerRunnable<Params,Result>(){
public Result call()throws Exception(
mTaskInvoked,set(true);
Process.setThreadPriority(PrOCesS.THREAD_PRIORITY_BACKGROUND);
//noinapection unchecked
return postResult(doInBackground (mParams));
   }
};

在AsyncTask的构造函数中创建了WorkRunnable对象.在FutrueTask中调用的run方法中会调用WorkRunnable的call方法,在call方法内部,首先设置了当前任务是否被调用设置为为true,设置了线程优先级,在最后调用了postResult()函数,其传入类型是Result类型,形参传入的是doInBackground方法,到此,后台任务的执行,就是在此处执行的;

private Result postResult(Result result){
@suppressWarnings("unchecked")
Message message"aHandler,obtainMessage (MESSAGE_POST RESULT,
new AsyneraskResult<Result>(this,result));
message.sendToTarget();
return result;
}

在postResult()内部,将result通过handler设定标签为MEASSGAE_POST_RESULT了发送回了Handler进行执行;

private atatic final InternalHandler sHandler=new InternalHandler();
private static class InternalHandler extends Handler{
eSuppressWarninga(i"unchecked","RavUseofParaneterizedType"})
@override
public void handleMessage(Message msg)(
AayncTaskResult reault-(AayncTaskResult)msg.obj;
switch (msg.what){
case MESSAGE POST RESULT:
//There is only one reault
result.mTask.finish(result.mData[0]);
breakcase MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate (result.mDatal:
break;
    }
  }
}

在handlerMessage中该标签下,调用了AsyncTask函数的finish方法;

private void finish(Result result){
if(isCancelled()){
onCancelled(result);
}else{
onPostExecute(result);
}
mStatus=Status.FINISHED;
}

在finish方法内部,判断了isCancelled是否取消,当取消就调用了onCanclled,当未取消则调用onPostExecutor方法,至此,AsyncTask内部实现的原理分析完成.


AsyncTask执行的串行和并发:

在Android3.0以前AsyncTask是并发执行,在之后则默认为是串行执行,所以在3.0以后如果需要并发执行,则调用时将execute转换为executeOnExecutor即可.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值