linux异步实现原理,Android异步处理四:AsyncTask的实现原理

分析:

在分析实现流程之前,我们先了解一下AsyncTask有哪些成员变量。

privatestaticfinalintCORE_POOL_SIZE =5;//5个核心工作线程

privatestaticfinalintMAXIMUM_POOL_SIZE =128;//最多128个工作线程

privatestaticfinalintKEEP_ALIVE =1;//空闲线程的超时时间为1秒

privatestaticfinalBlockingQueue sWorkQueue =

newLinkedBlockingQueue(10);//等待队列

privatestaticfinalThreadPoolExecutorsExecutor =newThreadPoolExecutor(CORE_POOL_SIZE,

MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue,sThreadFactory);//线程池是静态变量,所有的异步任务都会放到这个线程池的工作线程内执行。

回到例子中,点击按钮之后会新建一个GetCSDNLogoTask对象:

GetCSDNLogoTask task =newGetCSDNLogoTask();

此时会调用父类AsyncTask的构造函数:

AsyncTask.java

publicAsyncTask() {

mWorker =newWorkerRunnable() {

publicResult call()throwsException {

Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

returndoInBackground(mParams);

}

};

mFuture =newFutureTask(mWorker) {

@Override

protectedvoiddone() {

Message message;

Result result =null;

try{

result = get();

}catch(InterruptedException e) {

Android.util.Log.w(LOG_TAG, e);

}catch(ExecutionException e) {

thrownewRuntimeException("An error occured while executing doInBackground()",

e.getCause());

}catch(CancellationException e) {

message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,

newAsyncTaskResult(AsyncTask.this, (Result[])null));

message.sendToTarget();//取消任务,发送MESSAGE_POST_CANCEL消息

return;

}catch(Throwable t) {

thrownewRuntimeException("An error occured while executing "

+"doInBackground()", t);

}

message = sHandler.obtainMessage(MESSAGE_POST_RESULT,

newAsyncTaskResult(AsyncTask.this, result));//完成任务,发送MESSAGE_POST_RESULT消息并传递result对象

message.sendToTarget();

}

};

}

WorkerRunnable类实现了callable接口的call()方法,该函数会调用我们在AsyncTask子类中实现的doInBackground(mParams)方法,由此可见,WorkerRunnable封装了我们要执行的异步任务。FutureTask中的protected void done() {}方法实现了异步任务状态改变后的操作。当异步任务被取消,会向UI线程传递MESSAGE_POST_CANCEL消息,当任务成功执行,会向UI线程传递MESSAGE_POST_RESULT消息,并把执行结果传递到UI线程。

由此可知,AsyncTask在构造的时候已经定义好要异步执行的方法doInBackground(mParams)和任务状态变化后的操作(包括失败和成功)。

当创建完GetCSDNLogoTask对象后,执行

task.execute("http://www.linuxidc.com/pic/logo.gif");

此时会调用AsyncTask的execute(Params...params)方法

AsyncTask.java

publicfinalAsyncTask execute(Params... params) {

if(mStatus != Status.PENDING) {

switch(mStatus) {

caseRUNNING:

thrownewIllegalStateException("Cannot execute task:"

+" the taskis already running.");

caseFINISHED:

thrownewIllegalStateException("Cannot execute task:"

+" the taskhas already been executed "

+"(a task canbe executed only once)");

}

}

mStatus = Status.RUNNING;

onPreExecute();//运行在ui线程,在提交任务到线程池之前执行

mWorker.mParams = params;

sExecutor.execute(mFuture);//提交任务到线程池

returnthis;

}

当任务正在执行或者已经完成,会抛出IllegalStateException,由此可知我们不能够重复调用execute(Params...params)方法。在提交任务到线程池之前,调用了onPreExecute()方法。然后才执行sExecutor.execute(mFuture)是任务提交到线程池。

前面我们说到,当任务的状态发生改变时(1、执行成功2、取消执行3、进度更新),工作线程会向UI线程的Handler传递消息。在《Android异步处理三:Handler+Looper+MessageQueue深入详解》一文中我们提到,Handler要处理其他线程传递过来的消息。在AsyncTask中,InternalHandler是在UI线程上创建的,它接收来自工作线程的消息,实现代码如下:

AsyncTask.java

privatestaticclassInternalHandlerextendsHandler {

@SuppressWarnings({"unchecked","RawUseOfParameterizedType"})

@Override

publicvoidhandleMessage(Message msg) {

AsyncTaskResult result =(AsyncTaskResult) msg.obj;

switch(msg.what) {

caseMESSAGE_POST_RESULT:

// There is onlyone result

result.mTask.finish(result.mData[0]);//执行任务成功

break;

caseMESSAGE_POST_PROGRESS:

result.mTask.onProgressUpdate(result.mData);//进度更新

break;

caseMESSAGE_POST_CANCEL:

result.mTask.onCancelled();//取消任务

break;

}

}

}

当接收到消息之后,AsyncTask会调用自身相应的回调方法。

总结:

1、 AsyncTask的本质是一个静态的线程池,AsyncTask派生出的子类可以实现不同的异步任务,这些任务都是提交到静态的线程池中执行。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值