Android随笔-神经系统Handler

📅 2026/7/6 21:26:00
Android随笔-神经系统Handler
一、Handler 的作用作用说明线程间通信子线程发送消息到主线程更新 UI定时/延时执行延迟发送消息或定时重复任务任务调度将任务投递到指定线程的 Looper 中排队执行二、核心原理四组件协作组件职责Handler发送消息sendMessage/post、处理消息handleMessage/RunnableMessage承载数据what、arg1、arg2、obj、目标 Handlertarget、回调callbackMessageQueue按执行时间排序的链表队列管理消息的入队/出队Looper通过ThreadLocal绑定线程无限循环从队列取消息分发关键源码Looper.prepare() — 创建并绑定线程staticfinalThreadLocalLoopersThreadLocalnewThreadLocal();publicstaticvoidprepare(){if(sThreadLocal.get()!null){thrownewRuntimeException(Only one Looper may be created per thread);}sThreadLocal.set(newLooper(quitAllowed));}Looper.loop() — 无限循环publicstaticvoidloop(){finalLoopermemyLooper();finalMessageQueuequeueme.mQueue;for(;;){// 死循环Messagemsgqueue.next();// 阻塞等待epoll_waitif(msgnull)return;msg.target.dispatchMessage(msg);// 分发到 Handlermsg.recycleUnchecked();// 回收复用}}MessageQueue.next() — 阻塞与唤醒Messagenext(){for(;;){nativePollOnce(ptr,nextPollTimeoutMillis);// epoll 阻塞线程休眠synchronized(this){MessagemsgmMessages;if(msg!null){if(nowmsg.when){nextPollTimeoutMillis(int)(msg.when-now);// 计算等待时间}else{mMessagesmsg.next;// 取出消息returnmsg;}}}}}Handler.sendMessage() — 入队并唤醒publicbooleansendMessageAtTime(Messagemsg,longuptimeMillis){msg.targetthis;// 标记目标 Handlerreturnqueue.enqueueMessage(msg,uptimeMillis);}// MessageQueue.enqueueMessagebooleanenqueueMessage(Messagemsg,longwhen){synchronized(this){// 按时间插入链表// ...if(needWake){nativeWake(mPtr);// 写入 eventfd唤醒 epoll_wait}}}Handler.dispatchMessage() — 三种回调优先级publicvoiddispatchMessage(Messagemsg){if(msg.callback!null){// 优先级1post(Runnable) 的 callbackhandleCallback(msg);}else{if(mCallback!null){// 优先级2构造时的 Callback 接口if(mCallback.handleMessage(msg))return;}handleMessage(msg);// 优先级3子类重写的方法}}三、典型应用1. 子线程更新 UInewThread(()-{finalStringresultloadData();newHandler(Looper.getMainLooper()).post(()-{textView.setText(result);});}).start();2. 延时/定时任务HandlerhandlernewHandler(Looper.getMainLooper());// 延时 3 秒handler.postDelayed(()-hideLoading(),3000);// 定时轮询RunnabletasknewRunnable(){publicvoidrun(){refresh();handler.postDelayed(this,5000);}};handler.postDelayed(task,5000);3. HandlerThread — 自带 Looper 的工作线程HandlerThreadthreadnewHandlerThread(Worker);thread.start();HandlerworkernewHandler(thread.getLooper()){OverridepublicvoidhandleMessage(Messagemsg){// 在 Worker 线程执行耗时操作}};worker.sendEmptyMessage(1);4. 系统框架中的 Handler场景作用ActivityThread主线程消息循环处理四大组件生命周期回调ViewRootImpl通过 Choreographer 调度 UI 绘制measure/layout/drawChoreographer接收 VSYNC 信号同步屏障保障绘制优先Binder 线程ApplicationThread通过 Handler 将 IPC 回调切换到主线程四、王者地位Handler 在 Android 中的地位是 “线程通信的基石消息驱动的灵魂”。整个 Android 系统框架几乎建立在Handler Looper MessageQueue这套消息机制之上。1. 系统框架中的核心地位1.1 主线程的生命线// ActivityThread.java —— App 启动入口publicstaticvoidmain(String[]args){Looper.prepareMainLooper();// 创建主线程 LooperActivityThreadthreadnewActivityThread();thread.attach(false,startSeq);// 获取主线程 Handlerif(sMainThreadHandlernull){sMainThreadHandlerthread.getHandler();// H 类 Handler}Looper.loop();// 进入消息循环永不退出}没有 Handler/Looper主线程无法运行App 直接崩溃。1.2 四大组件的生命周期调度所有 Activity、Service、BroadcastReceiver 的生命周期回调都是通过 ActivityThread.H 这个 Handler 分发到主线程的// ActivityThread.java 内部类 HclassHextendsHandler{publicstaticfinalintLAUNCH_ACTIVITY100;publicstaticfinalintPAUSE_ACTIVITY101;publicstaticfinalintSTOP_ACTIVITY_SHOW103;publicstaticfinalintRESUME_ACTIVITY107;publicstaticfinalintDESTROY_ACTIVITY109;publicstaticfinalintBIND_APPLICATION110;publicstaticfinalintEXIT_APPLICATION111;publicstaticfinalintRECEIVER113;publicstaticfinalintCREATE_SERVICE114;publicstaticfinalintSERVICE_ARGS115;publicstaticfinalintSTOP_SERVICE116;// ... 更多OverridepublicvoidhandleMessage(Messagemsg){switch(msg.what){caseLAUNCH_ACTIVITY:handleLaunchActivity((ActivityClientRecord)msg.obj);break;casePAUSE_ACTIVITY:handlePauseActivity((IBinder)msg.obj);break;caseRESUME_ACTIVITY:handleResumeActivity((IBinder)msg.obj);break;// ... 所有生命周期方法都在这里}}}Binder 线程收到 AMS 的 IPC 调用 → 封装成 Message → 通过 H Handler 切换到主线程执行。1.3. View 的绘制与事件分发// ViewRootImpl.javafinalViewRootHandlermHandlernewViewRootHandler();// 申请 UI 绘制voidscheduleTraversals(){if(!mTraversalScheduled){mTraversalScheduledtrue;// 同步屏障阻塞普通消息保障绘制优先mTraversalBarriermHandler.getLooper().getQueue().postSyncBarrier();// 通过 Choreographer 注册 VSYNC 回调mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL,mTraversalRunnable,null);}}// 执行 measure / layout / drawfinalclassTraversalRunnableimplementsRunnable{publicvoidrun(){doTraversal();}}没有 HandlerView 无法绘制屏幕永远是黑的。1.4. 输入事件的流转// Input 事件流程InputDispatcher(Native,system_server)↓ 通过InputChannel(SocketPair)InputEventReceiver(App,子线程)↓ 封装成MessageNativeInputEventReceiver→ViewRootImpl.mHandler ↓ 切换到主线程DecorView.dispatchTouchEvent()→Activity.dispatchTouchEvent()↓ViewGroup.dispatchTouchEvent()→ 子ViewInput 事件从底层到应用层最终通过 Handler 切换到主线程处理。2. 与其他核心机制的关联机制Handler 的作用Binder IPCApplicationThread通过 Handler 将 AMS 的 IPC 回调切换到主线程Choreographer基于 Handler 同步屏障 VSYNC 实现帧调度AsyncTask底层使用InternalHandler切换线程LiveData通过Dispatchers.Main或 Handler 确保主线程更新RxJavaAndroidSchedulers.mainThread()内部使用 Handler协程 (Kotlin)Dispatchers.Main基于 Handler 实现Jetpack 组件ViewModel、Room等异步回调通过 Handler 切回主线程3. 地位五、常见问题1. 内存泄漏原因非静态内部类持有外部 Activity 引用延迟消息未执行时 Activity 无法回收。// 错误写法privateHandlermHandlernewHandler(){// 匿名内部类持有 ActivitypublicvoidhandleMessage(Messagemsg){textView.setText(...);// 持有 Activity 引用链}};mHandler.sendEmptyMessageDelayed(1,10*60*1000);// 10分钟后执行解决方案// 静态内部类 WeakReferenceprivatestaticclassSafeHandlerextendsHandler{privatefinalWeakReferenceActivitymRef;SafeHandler(Activityactivity){mRefnewWeakReference(activity);}OverridepublicvoidhandleMessage(Messagemsg){ActivityactivitymRef.get();if(activitynull||activity.isFinishing())return;// 处理消息}}// 同时 onDestroy 中移除消息OverrideprotectedvoidonDestroy(){super.onDestroy();mHandler.removeCallbacksAndMessages(null);}2. 子线程创建 Handler 崩溃// 错误子线程默认没有 LoopernewThread(()-{newHandler();// RuntimeException: No Looper}).start();// 正确手动创建 LoopernewThread(()-{Looper.prepare();HandlerhandlernewHandler();Looper.loop();}).start();3. 主线程 loop() 是死循环为什么没 ANRLooper.loop() 的 for(; 本身不会导致 ANR。ANR是因为消息处理耗时过长阻塞了后续消息如输入事件、绘制消息。// 不会 ANRloop 只是循环取消息for(;;){Messagemsgqueue.next();// 无消息时 epoll 阻塞线程休眠不耗 CPUmsg.target.dispatchMessage(msg);// ANR 发生在这里处理耗时}4. Message.obtain() vs new Message()// 推荐从消息池复用避免 GCMessagemsgMessage.obtain();msg.what1;handler.sendMessage(msg);// 不推荐频繁创建对象MessagemsgnewMessage();// 每次 new增加 GC 压力5. postDelayed 不准确延迟时间是入队时间不是精确的执行时间。如果消息队列前面有耗时消息实际执行会延后。6. 同步屏障Sync Barrier是什么系统框架内部机制阻塞所有同步消息只允许异步消息通过。用于保障 Choreographer 的 UI 绘制CALLBACK_TRAVERSAL优先执行避免掉帧。应用层无法直接调用。六、总结Handler 线程间邮差。把任务打包成 Message投递到目标线程的 MessageQueue由 Looper 按顺序取出回调 Handler 执行。底层通过 ThreadLocal 实现线程隔离通过 epoll eventfd 实现阻塞与唤醒。Handler 是 Android 的神经系统——没有它主线程无法呼吸组件无法存活UI 无法绘制App 就是一具空壳。