博客主页java
前面分析完了Handler源码,可是还有不少鲜为人知的秘密,接下来分析它。android
涉及到的类:
HandlerThread、IntentService、AsyncTask、Messenger、IdleHandler、Looper.Observer、MessageLogging等express
上半部分讲解内容:HandlerThread、IntentService、AsyncTask
下半部分讲解内容:Messenger、IdleHandler、Looper.Observer、MessageLoggingsegmentfault
背景:在Android系统中使用消息机制进行线程间的消息传递。若是要在子线程中传递消息,就须要建立一个子线程的Handler。并发
new Thread(new Runnable() { @Override public void run() { Looper.prepare(); Handler workHandler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(@NonNull Message msg) { // 处理子线程的消息 return false; } }); // 发送消息 workHandler.sendEmptyMessage(0); Looper.loop(); } }).start();
这种方式虽然能够实如今子线程中进行消息的传递,但很麻烦且该子线程不能退出循环。Android为咱们提供了很好的组件HandlerThread。异步
查看源码发现,HandlerThread是继承Thread,在内部维护一个Looper,当线程开启后run方法运行起来,就会建立一个Looper。定义以下:async
/** * A {@link Thread} that has a {@link Looper}. * The {@link Looper} can then be used to create {@link Handler}s. * <p> * Note that just like with a regular {@link Thread}, {@link #start()} must still be called. */ public class HandlerThread extends Thread {}
它的主要做用:处理单线程的耗时任务。ide
建立HandlerThread(须要指定线程的名字)后,必须先启动HandlerThread线程。oop
HandlerThread handlerThread = new HandlerThread("AsyncThreadTask"); handlerThread.start(); // 启动线程 // 建立Handler时须要指定HanderThread中建立的Looper对象 Handler workHandler = new Handler(handlerThread.getLooper()); // 发送消息 workHandler.post(new Runnable() { @Override public void run() { // 处理耗时任务 } }); // 退出消息循环,发送的消息就不会被处理了 handlerThread.quit();
HandlerThread的源码很简单只有100多行,先来看下它的构造方法源码分析
// HandlerThreadde.java源码 int mPriority; // 线程优先级 public HandlerThread(String name) { super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; } public HandlerThread(String name, int priority) { super(name); mPriority = priority; }
构造方法参数有两个:
线程start()后run方法执行,当前线程绑定Looper对象,并循环该线程中的消息。
// HandlerThreadde.java源码 Looper mLooper; // 当前线程持有的Looper对象 // Looper已经建立完成调用 protected void onLooperPrepared() { } @Override public void run() { mTid = Process.myTid(); Looper.prepare(); // 建立Looper对象 synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); // 唤醒等待的线程 } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); // mTid = -1; }
提供了获取当前线程的Looper的方法。
// HandlerThreadde.java源码 public Looper getLooper() { if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; }
若是当前线程没有运行,直接返回null;若是当前线程已经运行,但Looper尚未建立完成,则wait,等待Looper建立完成,不然直接返回该线程的Looper对象。
背景:在Android应用的程序中,若是Service中处理耗时的操做,很容易出现ANR的现象,一般的作法就是,在onStartCommon方法中开启一个子线程而后内部执行耗时的操做,在执行完毕后若是中止服务,还须要手动的在子线程的run方法中调用stopSelf()来中止服务。
其实IntentService,就是Service 和 HandlerThread 的结合体。
IntentService定义的三个基本点:是什么?怎么用?如何work?
/** 一、是什么? IntentService is a base class for {@link Service}s that handle asynchronous requests (expressed as {@link Intent}s) on demand. 二、怎么用? Clients send requests through {@link android.content.Context#startService(Intent)} calls; 三、如何work? the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work. */ public abstract class IntentService extends Service {}
一、IntentService特色
二、 IntentService的优势和缺点
IntentService相对与Service的好处:
可是它的缺点也显而易见:
一、IntentService是一个抽象类,内部有一个抽象方法onHandleIntent。
public class MyIntentService extends IntentService { public MyIntentService() { super("MyIntentService"); } @Override protected void onHandleIntent(@Nullable Intent intent) { Log.d(TAG, "onHandleIntent: " + Thread.currentThread().getName()); } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy"); } }
二、清单文件AndroidManifest中配置
// AndroidManifest.xml <service android:name=".MyIntentService" />
三、调用startService(Intent)启动IntentService
Intent service = new Intent(this, MyIntentService.class); startService(service);
一、IntentService是Service的子类,拥有Service的全部生命周期方法,内部还有一个ServiceHandler
// IntentService.java源码 public abstract class IntentService extends Service { // ServiceHandler继承Handler,建立时必须传入一个Looper 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); } } public IntentService(String name) { super(); mName = name; } protected abstract void onHandleIntent(@Nullable Intent intent); }
二、onCreate()的源码,建立HandlerThread。
// IntentService.java源码 @Override public void onCreate() { super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); }
IntentService服务开启后就会建立Handler线程(HandlerThread),并获取当前线程的Looper对象,而后关联到Handler中。
三、接下来是onStart()源码,调用mServiceHandler
@Override public void onStart(@Nullable Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); } @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; }
当你启动IntentService的时候,就会产生一条附带startId和Intent的 Message并发送到MessageQueue中,接下来Looper发现MessageQueue中有Message的时候,就会中止Handler 处理消息。
四、handleMessage处理消息的代码
public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); }
接着调用 onHandleIntent((Intent)msg.obj),这是一个抽象的方法,其实就是咱们要重写实现的方法,咱们能够在这个方法里面处理咱们的工做.当任务完成时就会调用stopSelf(msg.arg1)这个方法来结束指定的工做。
五、stopSelf(msg.arg1)
回调完成后回调用 stopSelf(msg.arg1),注意这个msg.arg1是个int值,至关于一个请求的惟一标识。每发送一个请求,会生成一个惟一的标识,而后将请求放入队列,当所有执行完成(最后一个请求也就至关于getLastStartId == startId),或者当前发送的标识是最近发出的那一个(getLastStartId == startId),则会销毁咱们的Service.若是传入的是-1则直接销毁。
六、onDestroy()
@Override public void onDestroy() { mServiceLooper.quit(); }
服务结束后调用这个方法 mServiceLooper.quit()使looper停下来。
一、在源码handleMessage方法中为何执行完handleIntent方法会去调用带参数的stopSelf()
由于stopSelf()的执行会马上将服务中止掉(内部实现调用带参数的stopSelf,传入的值是-1),而带参数的stopSelf(int startId)会在全部任务执行完毕后将服务给中止。一般状况下调用stopSelf(int satrtId)方法不会马上去执行中止服务的操做,会去判断最近执行任务的getLastStartId是否和startId相等,若是相等就马上执行中止服务的操做。
为了简化在子线程中访问UI的过程,系统提供了AsyncTask,但不一样的API版本AsyncTask具备不一样的表现。
AsyncTask是一种轻量级的异步任务类,能够在线程池中执行后台任务,而后把执行的进度和最终结果传递给主线程中更新UI。AsyncTask=Thread+Handler
AsyncTask是一个抽象的泛型类,它提供了Params,Progress,Result这三个泛型参数。
public abstract class AsyncTask<Params, Progress, Result> { }
AsyncTask提供了4个核心方法
一、 onPreExecute() 在主线程中执行,在异步任务执行以前,此方法会被调用,通常用于作一些准备工做
二、doInBackground(Params... params) 在线程池中执行,此方法用于执行异步任务,params参数表示异步任务的输入参数。在此方法中能够经过publishProgress方法来更新任务的进度,publishProgress方法会调用onProgressUpdate方法。此方法须要返回计算结果给onPostExecute方法。
三、onProgressUpdate(Progress... values),在主线程中执行,当后台任务的执行进度发生改变时经过publishProgress方法更新后此方法会被调用。
四、onPostExecute(Result result) 在主线程中执行,在异步任务执行以后,此方法会被调用,其中result参数就是后台任务的返回值,即doInBackground的返回值
除了这个四个方法外,还提供了onCancelled()方法,也是在主线程中执行,当任务被取消时会被调用,但onPostExecute不会被调用。
一、为了分析AsyncTask的工做原理,从execute方法开始分析,execute方法又会调用executeOnExecutor方法
// AsyncTask.java源码 @MainThread public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); } @MainThread 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; }
sDefaultExecutor是一个串行的线程池,一个进程中全部的AsyncTask所有在这个串行的线程池中排队执行。在executeOnExecutor方法中,AsyncTask的onPreExecute方法最早执行,而后线程池开始执行。
二、分析线程池的执行过程
public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; private static class SerialExecutor implements Executor { final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); 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() { // 从队列的头部获取一个任务,并赋值给mActive。当队列为空,mActive就为null if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } } }
SerialExecutor的execute的方法把一个任务插入到任务队列mTasks中,若是此时mActive为null,表示没有正在活动的任务,就会调用SerialExecutor的scheduleNext方法来执行下一个任务,当执行完任务后,会从队列中获取下一个任务执行,若是任务队列中没有任务就执行完成。
三、AsyncTask中有两个线程池(SerialExecutor和THREAD_POOL_EXECUTOR)和一个Handler(InternalHandler),
在AsyncTask的构造方法中,因为FutureTask的run会调用mWorker的call方法,因此mWorker的call方法最终在线程池中执行。
// AsyncTask的构造方法 mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Result result = null; try { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked result = doInBackground(mParams); } catch (Throwable tr) { mCancelled.set(true); throw tr; } finally { postResult(result); } return result; } }; 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); } } };
在doInBackground执行完后,将返回结果传给postResult方法
private Result postResult(Result result) { Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; } private static class InternalHandler extends Handler { public InternalHandler(Looper looper) { super(looper); } @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; } } }
Handler收到MESSAGE_POST_RESULT这个消息后会调用AsyncTask的finish方法
private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }
若是消息被取消了,执行onCancelled方法,不然调用onPostExecute方法。
若是个人文章对您有帮助,不妨点个赞鼓励一下(^_^)