AysncTask
AsyncTask本质上是一个Handler和线程池的封装,线程池用来异步处理后台任务,handler用来发送消息进行UI方面的交互
优点:
- 适合简单短时的异步任务,可以同时爆发数量较大的异步任务(支持线程池,任务队列128个,最多同时并发5个)
- 过程可控(即onPreExecute、doInBackground、onPostExecute等)
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 != Status.PENDING) {
switch (mStatus) {
case RUNNING:
throw new IllegalStateException("Cannot execute task:"
+ " the task is already running.");
case FINISHED:
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;
}
这里调用onPreExecute后开始触发线程池 ,跑子线程。线程池中最终运行mFuture的run方法,run调用innerRun
void innerRun() {
if (!compareAndSetState(READY, RUNNING))
return;
runner = Thread.currentThread();
if (getState() == RUNNING) { // recheck after setting thread
V result;
try {
result = callable.call();
} catch (Throwable ex) {
setException(ex);
return;
}
set(result);
} else {
releaseShared(0); // cancel
}
}
这边的callable.call其实就是调用WorkerRunnable.call
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
return postResult(doInBackground(mParams));
}
很明显就是在线程内部调用了doInBackground,之后把doInBackground的结果作为参数调用postResult;这里先揭秘下,postResult会利用Handler回到主线程调用onPostExecute
private Result postResult(Result result) {
Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
private static class InternalHandler extends Handler {
@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:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
可以看到这边有handleMessage有两个分支一个分支finish最终调用onPostExecute,另一个onProgressUpdate是更新进度的
HandlerThread
HandlerThread本质上就是一个Thread和Looper的封装。与AsyncTask的区别在于,AsyncTask适合短时并发数多的小任务,HandlerThread适合耗时多数据量大的任务。但HandlerThread同时只能执行一个任务,多个任务会以队列的形式串行执行。
优点:
- 结构清晰,功能定义明确
- 对于多个后台任务时,简单,清晰
用法
HandlerThread mHandlerThread = new HandlerThread("MyHandlerThread");
mHandlerThread.start();
//HandlerThread内部的Looper,这边的代码会在HandlerThread里的子线程中执行
Handler handler = new Handler(mHandlerThread.getLooper()){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//这里可以执行异步任务,执行完可调用mMainHandler回到主线程刷新UI
}
};
//发送消息触发HandlerThread的handler,执行异步任务
handler.sendEmptyMessage(1);
//这种用法与sendMessage差不多,只不过这边的Message自带里处理Callback即Runnable的处理
handler.post(new Runnable() {
@Override
public void run() {
}
});
//主线程的Looper
Handler mMainHandler = new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//更新UI
}
};
//清空HandlerThread内部消息
mHandlerThread.quit();//清空所有消息
mHandlerThread.quitSafely();//只清空延迟消息
HandlerThread源码
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
protected void onLooperPrepared() {
}
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll(); //唤醒其他线程的等待锁,这边是为了唤醒getLooper()方法中的等待锁
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// 线程开始,该方法会一直等待Looper对象创建完成才会执行,
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
public int getThreadId() {
return mTid;
}
}
源码很短,没有太多难点主要是一些细节处理。
IntentService
IntentService本质上是一个Service和HandlerThread的封装。
优点:
- IntentService创建独立线程来处理Intent请求
- IntentService处理请求后会自动停止
注意点:IntentService只能使用bindService,如果用startService来启动的话则onHandleIntent则不会被调用,失去IntenService的 意义,变得跟普通Service一样。