Android的主线程主要是运行四大组件以及处理其与用户的交互;而子线程用于执行耗时任务,如网络请求,I/O操作。
限制:
* AsyncTask的类必须要在主线程中加载。所以第一次访问AsyncTask时需要在主线程中进行,Android 4.1以上会自动完成这个过程,在ActivityThread的main方法中。
* AsyncTask的对象必须在主线程中创建。
* execute方法必须在UI线程调用。
* 不要直接调用AsyncTask的关键方法。
* 一个AsyncTask对象只能执行一次,即execute只能调用一次,否则会抛出异常。
* 可以通过exectueOnExecutor来指定线程池执行任务。
原理:
从execute方法开始。execute会使用默认的线程池,即SerialExecutor。一个进程中所有的AsyncTask都会在这个线程池中排队(static成员):
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
public final AsyncTask execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
之后调用executeOnExecutor,先执行onPreExecute方法,然后线程池开始执行:
public final AsyncTask executeOnExecutor(Executor exec,
Params... params) {
...
mStatus = Status.RUNNING;
onPreExecute();
mWorker.mParams = params;
exec.execute(mFuture);
return this;
}
SerialExecutor的实现。在实例化AsyncTask的时候,会创建一个FutureTask对象,该类是一个并发类,充当了Runnable的作用,其中会包含execute传入的参数。当线程池开始执行,首先将当前的FutureTask对象插入到任务队列中,如果当前没有正在活动的任务,则调用scheduleNext方法执行下一个任务;同时一个任务执行完毕,也会调用scheduleNext方法执行下一个任务:
private static class SerialExecutor implements Executor {
final ArrayDeque mTasks = new ArrayDeque();
Runnable mActive;
public synchronized void execute(final Runnable r) {
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (mActive == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
scheduleNext方法则通过另一个线程池,THREAD_POOL_EXECUTOR去具体执行任务,该线程池是个并发线程池。默认情况下,AsyncTask会通过SERIAL_EXECUTOR接收Runnable,串行的每次执行一个,而具体的执行任务交由THREAD_POOL_EXECUTOR;可以让AsyncTask并发的去执行Runnable,只要在其execute方法中,直接指定THREAD_POOL_EXECUTOR这个线程池就可以了。
当任务开始执行,会调用FutureTask的run方法。在实例化AsyncTask的时候,会创建一个WorkerRunnable,同时绑定到FutureTask上,FutureTask的run方法会调用WorkerRunnable的call方法,此时doInBackground方法便会被执行:
public AsyncTask(@Nullable Looper callbackLooper) {
mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
? getMainHandler()
: new Handler(callbackLooper);
mWorker = new WorkerRunnable() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
postResult(result);
}
return result;
}
};
mFuture = new FutureTask(mWorker) {
...
};
}
doInBackground执行完毕,会调用postResult发送出结果,其任务就是通过AsyncTask内部的Handler发送一个msg:
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult(this, result));
message.sendToTarget();
return result;
}
该Handler在创建时,Looper指定为main looper,保证其回调发生在主线程。当任务处理完成,Handler在主线程中执行AsyncTask#finish方法,当更新进度则回调AsyncTask#onProgressUpdate方法:
private static class InternalHandler extends Handler {
public InternalHandler(Looper looper) {
super(looper);
}
@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;
}
}
}
finish方法中,则根据是否AsyncTask是否被取消了,去回调onCancel或者onPostExecute:
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
// during processing, and to have a static startService(Context, Intent)
// method that would launch the service & hand off a wakelock.
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
而Handler的具体实现,是回调onHandleIntent方法,将具体的任务实现交由其子类,任务执行完毕后调用stopSelf尝试停止service。所有任务完成后,service销毁:
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
client使用时,直接startService,IntentService#onStart方法中就会通过Handler将Intent包裹为msg发出,等待Looper去执行:
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
优点:
Android中的线程池为接口Executor,具体实现类为ThreadPoolExecutor,通过为其配置不同的参数,可以创建不同的线程池。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory) {
* corePoolSize:核心线程数。默认情况下,核心线程会在线程池中一直存活,即使处于闲置状态。
* maximumPoolSize:最大线程数。包括了核心线程和非核心线程。
* keepAliveTime:非核心线程闲置的超时时间,超过这个时间就就会被回收。当把allowCoreThreadTimeOut设置为true,同时也会作用于核心线程的。
* unit:keepAliveTime的时间单位。
* workQueue:线程池中的任务队列,通过execute方法提交的Runnable会添加到这里。
* threadFactory:创建线程时使用的工具类。
* RejectedExecutionHandler类型的不常用参数,用于指定,当无法执行新任务时,线程池会回调该handler的rejectedExecution方法,默认实现是直接抛出一个RejectedExecutionHaException异常。
ThreadPoolExecutor执行任务的规则:
1. 如果线程池中的核心线程数未达到上限,则直接启动一个核心线程去执行;
2. 如果核心线程数已达上限,则将任务插入到队列中排队;
3. 如果队列也满了,则尝试创建非核心线程去执行;
4. 如果总的线程数已经达到了上限,此时已经无法执行任务,此时便会调用RejectedExecutionHandler#rejectedExecution方法,通知调用者。
ThreadPoolExecutor在AsyncTask中的创建示例:
```
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
// We want at least 2 threads and at most 4 threads in the core pool,
// preferring to have 1 less than the CPU count to avoid saturating
// the CPU with background work
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final int KEEP_ALIVE_SECONDS = 30;
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
}
};
private static final BlockingQueue sPoolWorkQueue =
new LinkedBlockingQueue(128);
/**
* An {@link Executor} that can be used to execute tasks in parallel.
*/
public static final Executor THREAD_POOL_EXECUTOR;
static {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
sPoolWorkQueue, sThreadFactory);
threadPoolExecutor.allowCoreThreadTimeOut(true);
THREAD_POOL_EXECUTOR = threadPoolExecutor;
}
```
* 核心线程数为2~4个
* 最大线程数为2*Cpu核心数+1
* 核心线程有闲置超时
* 任务队列容量为128
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
// ScheduledThreadPoolExecutor.java
private static final long DEFAULT_KEEPALIVE_MILLIS = 10L;
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue());
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
}