前言
这篇文章文章讲下Handler的一些其他方面的应用(HandlerThread、 IntentService、Glide 如何做到生命周期的控制),所以需要对Handler原理有一定的理解 。如果对原理不是很理解,可以补下Handler 源码解析这篇文章
HandlerThread
HandlerThread是Thread的子类,就是一个线程,只是它在自己的线程里面帮我们创建了Looper
@Override
//线程start的时候会创建Looper
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
//调用的线程可能会挂起线程,保证线程安全
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 {
//等待Looper创建
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
我们可以看到上面两个方法中添加了同步锁机制,防止多线程操作中getLooper
返回为null,确保了线程安全。
使用
HandlerThread thread = new HandlerThread();
thread.start();
//代码会阻塞等待Looper 返回
Handler handler = new Handler(thread.getLooper());
//发送消息
handler.send.......;
//退出循环
handler.getLooper().quit();
handler.getLooper().quitSafely();
HandlerThread 存在的意义
- 方便使用
- 方便初始化
- 方便其他线程获取线程Looper
- 保证了线程安全
IntentService
大家可能非常熟悉了,但是这里我还是要拿过来再讲讲,重点还是Handler。因为IntentService对Handler的应用方面是个不错的例子。看代码
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
//5.处理任务
onHandleIntent((Intent)msg.obj);
//6.根据 startId 结束service
stopSelf(msg.arg1);
}
}
@Override
public void onCreate() {
super.onCreate();
//1.创建HanderThread 处理任务
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
//2.创建handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
//3.每次启动IntentService调用
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
//4.发送消息,并将当前启动的 startId 传过去
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public void onDestroy() {
//7.当所有所有startId 相关的任务都结束之后的 线程回收
mServiceLooper.quit();
}
上面代码注释从第1步到第7步,我们看到IntentService帮我们维护了所有后台的任务。这些任务通过Handler机制按照先后顺序执行,并且自动维护IntentService生命周期
IntentService 存在的意义
- 用于处理后台耗时的任务
- 可以用于任务的拆分,一项任务拆分若干个子任务,子任务按照顺序先后执行。子任务执行完之后,这项任务才算完成
- 管理好后台线程,保证只有一个线程处理工作,而且一个一个的完成任务,有条不紊的进行,直到所有任务完成,回收线程
Glide中的应用
Glide 相信大应该非常熟悉了,我们都知道Glide生命周期的控制(如果不了解,可以看下Glide相关文章的分析,跟LiveData 是同一个原理)是通过添加一个空的Fragment到Activity 或者Fragment中,然后通过FragmentMannager管理Fragment的生命周期,从而达到生命周期的控制。下面是节选了Glide一段添加Fragment的代码:
private RequestManagerFragment getRequestManagerFragment(
@NonNull final android.app.FragmentManager fm,
@Nullable android.app.Fragment parentHint,
boolean isParentVisible) {
//1.通过FragmentManager获取 RequestManagerFragment,如果已添加到FragmentManager则返回实例,否则为空
RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
//2.如果fm里面没有则从map缓存里取
current = pendingRequestManagerFragments.get(fm);
if (current == null) {
//3.第1和2步都没有,说明确实没创建,则走创建的流程
current = new RequestManagerFragment();
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
current.getGlideLifecycle().onStart();
}
//4.将新创建的fragment 保存到map容器
pendingRequestManagerFragments.put(fm, current);
//5.发送添加fragment事务事件
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
//6.发送remove 本地缓存事件
handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
//跟上面那个方法唯一的区别是 这个是Fragment 的FragmentManager,上面的是Acitivity 的FragmentManager
private SupportRequestManagerFragment getSupportRequestManagerFragment(
@NonNull final FragmentManager fm, @Nullable Fragment parentHint, boolean isParentVisible) {
SupportRequestManagerFragment current =
(SupportRequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = pendingSupportRequestManagerFragments.get(fm);
if (current == null) {
current = new SupportRequestManagerFragment();
current.setParentFragmentHint(parentHint);
if (isParentVisible) {
current.getGlideLifecycle().onStart();
}
pendingSupportRequestManagerFragments.put(fm, current);
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
handler.obtainMessage(ID_REMOVE_SUPPORT_FRAGMENT_MANAGER, fm).sendToTarget();
}
}
return current;
}
@Override
public boolean handleMessage(Message message) {
boolean handled = true;
Object removed = null;
Object key = null;
switch (message.what) {
case ID_REMOVE_FRAGMENT_MANAGER:
//7.移除缓存
android.app.FragmentManager fm = (android.app.FragmentManager) message.obj;
key = fm;
removed = pendingRequestManagerFragments.remove(fm);
break;
//省略代码...
}
//省略代码...
return handled;
}
看了上面的代码,大家可能会有疑惑。
- Fragment添加到FragmentManager为什么还要保存到map容器里(第4步)?
- 判断Fragment是否已添加为啥还要从map容器判断(第2步),FragmentManager 去find 不就可以做到了吗?
其实答案很简单,学了Handler原理之后我们知道:就是在第5步执行完之后并没有将Fragment添加到FragmentManager(事件排队中),而是发送添加Fragment的事件。接下来我们看代码
//FragmentManagerImpl.java
void scheduleCommit() {
synchronized (this) {
boolean postponeReady =
mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1;
if (postponeReady || pendingReady) {
mHost.getHandler().removeCallbacks(mExecCommit);
mHost.getHandler().post(mExecCommit);
updateOnBackPressedCallbackEnabled();
}
}
}
添加Fragment 最终会走到FragmentManagerImpl的 scheduleCommit
方法,我们可以看到他是通过Handler 发送事件。
这也就解释了为什么第5步执行完之后Fragment为什么没有立即添加到FragmentManager,所以需要Map缓存Fragment来标记是否有Fragment添加。再接着有了第6步发送移除Map缓存的消息,因为Handler处理消息是有序的。
总结
上面的几个列子可以充分说明了Handler应用的广泛,以及重要性。如果不理解Handler原理,也就无法理解代码的意图。