Android 进程与线程模型:Zygoteã€�主线程ã€�Binder çº¿ç¨‹æ± è§£æž�
引言:并�执行的基石与挑战
在 Android 系统ä¸ï¼Œæ‰€æœ‰åº”用程åº�代ç �都è¿�行在特定的进程和线程上下文ä¸ã€‚进程æ��供资æº�隔离和独立è¿�行的环境,线程则是 CPU 调度的基本å�•ä½�,负责执行具体的代ç �指令。ç�†è§£ Android 如何创建ã€�管ç�†ã€�调度进程(包括其生命周期ã€�ä¼˜å…ˆçº§å’Œç»ˆæ¢æœºåˆ¶ï¼‰ï¼Œä»¥å�Šå¦‚何在进程内有效地组织和管ç�†çº¿ç¨‹ï¼ˆä¸»çº¿ç¨‹ã€�Binder 线程ã€�å�Žå�°çº¿ç¨‹ï¼‰ï¼ŒåŒ…括它们之间的å�Œæ¥ä¸Žé€šä¿¡ï¼Œå¯¹äºŽæž„建稳定ã€�æµ�ç•…ã€�å“�应迅速的应用至关é‡�è¦�。
对于 Android 专家而言,仅仅掌æ�¡ Thread 的基本用法或知é�“ UI æ“�作è¦�在主线程执行是远远ä¸�够的。必须深入ç�†è§£ Linux 进程/线程的底层基础ã€�Android 独特的进程生命周期与 OOM 优先级调整机制(oom_adj)ã€�主线程的至高地ä½�与性能瓶颈ã€�Binder çº¿ç¨‹æ± çš„å·¥ä½œåŽŸç�†ã€�高级å�Žå�°ä»»åС处ç�†ç–ç•¥ã€�Handler/Looper 消æ�¯æœºåˆ¶çš„内部细节ã€�å¤�æ�‚场景下的线程å�Œæ¥æŠ€æœ¯ï¼Œä»¥å�Š ANR(Application Not Responding)的系统性分æž�方法。这ç§�深层次的ç�†è§£æ˜¯è§£å†³å¹¶å�‘问题ã€�优化å“�应速度ã€�分æž�系统级异常行为的基础。
本文将深入探讨 Android 的进程与线程模型,涵盖以下内容:
底层基础:Linux 进程与线程概念回顾
Android 进程:Zygote åµåŒ–ã€�生命周期ã€�优先级与 OOM Killer(oom_adj)
主线程剖�:UI 线程的关键�责与性能约�
Binder 线程:处ç�† IPC çš„æ ¸å¿ƒçº¿ç¨‹æ±
å�Žå�°çº¿ç¨‹ç–略:ExecutorServiceã€�Coroutines ç‰çް代并å�‘方案
Handler 机制详解:Looper�MessageQueue�ThreadLocal 的内部�作
高级å�Œæ¥ï¼šé”�ã€�原å�ç±»ã€�å¹¶å�‘工具(CountDownLatchã€�Semaphore ç‰ï¼‰çš„原ç�†ä¸Žåº”用
ANR 深度分æž�:系统性地诊æ–å’Œè§£å†³åº”ç”¨æ— å“�应问题
一�底层基础:Linux 进程与线程模型
Android 构建于 Linux å†…æ ¸ä¹‹ä¸Šï¼Œå…¶è¿›ç¨‹å’Œçº¿ç¨‹æ¨¡åž‹ç›´æŽ¥ç»§æ‰¿è‡ª Linux。
进程(Process)
是程�执行时的一个实例
拥有独立的虚拟地å�€ç©ºé—´ã€�内å˜ã€�æ•°æ�®æ ˆä»¥å�Šæ–‡ä»¶æ��述符ç‰ç³»ç»Ÿèµ„æº�
进程间相互隔离,通信需�通过 IPC 机制(如 Binder�Socket�Pipe)
Linux 通过 fork() 系统调用创建å�进程(å¤�制父进程地å�€ç©ºé—´ï¼‰ï¼Œé€šå¸¸å�进程会接ç�€è°ƒç”¨ exec() 系列系统调用æ�¥åŠ è½½å¹¶æ‰§è¡Œæ–°çš„ç¨‹åº�镜åƒ�
线程(Thread)
是进程内的一个执行�元,是 CPU 调度的基本��
å�Œä¸€è¿›ç¨‹å†…的线程共享该进程的虚拟地å�€ç©ºé—´ã€�内å˜èµ„æº�(代ç �段ã€�æ•°æ�®æ®µã€�å †å†…å˜ï¼‰å’Œæ–‡ä»¶æ��述符
æ¯�个线程拥有自己独立的程åº�计数器ã€�寄å˜å™¨ã€�çº¿ç¨‹æ ˆï¼ˆç”¨äºŽå˜å‚¨å±€éƒ¨å�˜é‡�和函数调用信æ�¯ï¼‰
线程间的切�(上下文切�)通常比进程切�开销�得多
Linux å†…æ ¸ä¸ï¼Œçº¿ç¨‹ï¼ˆLightweight Process, LWP)是通过 clone() 系统调用以特定å�‚数创建的,它æ��供了比 fork() æ›´ç�µæ´»çš„资æº�共享选项。用户空间通常使用 POSIX 线程库(pthread)æ�¥åˆ›å»ºå’Œç®¡ç�†çº¿ç¨‹
Android 应用上下文
æ¯�个 Android 应用默认è¿�行在一个独立的 Linux 进程ä¸ï¼Œæ‹¥æœ‰å”¯ä¸€çš„ UID(用户 ID)和 GID(组 ID),实现了应用间的安全沙箱隔离。应用内的所有代ç �ï¼Œæ— è®ºæ˜¯ Java/Kotlin 还是 Native,都执行在属于该进程的æŸ�个线程上。
二�Android 进程模型:被管�的生命周期与优先级
Android 系统对应用进程的管ç�†è¿œæ¯”æ ‡å‡† Linux æ›´ä¸ºä¸¥æ ¼å’Œä¸»åŠ¨ï¼Œæ ¸å¿ƒç›®æ ‡æ˜¯ä¿�障系统æµ�畅性和用户体验。
Zygote åµåŒ–进程
如å‰�所述,所有应用进程(以å�Š SystemServer)都由 Zygote 进程通过 fork() 创建。这使得新进程能够快速å�¯åŠ¨å¹¶å…±äº«å†…å˜ï¼ˆCopy-on-Write)。
进程生命周期与状�(� AMS 管�)
Android ç³»ç»Ÿæ ¹æ�®åº”用组件的状æ€�å’Œç”¨æˆ·äº¤äº’æƒ…å†µï¼Œå°†è¿›ç¨‹å¤§è‡´åˆ†ä¸ºå‡ ä¸ªä¼˜å…ˆçº§ç±»åˆ«ï¼Œè¿™ç›´æŽ¥å†³å®šäº†è¿›ç¨‹åœ¨å†…å˜ä¸�足时被æ�€æ»çš„å�¯èƒ½æ€§ã€‚
��进程(Foreground Process)
用户当å‰�æ£åœ¨äº¤äº’的应用(顶部的 Activity 处于 Resumed 状æ€�)
托管�与用户交互的 Activity 绑定的 Service
托管ç�€è°ƒç”¨äº† startForeground() çš„ Service(显示æŒ�ç»é€šçŸ¥ï¼‰
托管ç�€æ£åœ¨æ‰§è¡Œç”Ÿå‘½å‘¨æœŸå›žè°ƒï¼ˆonCreateã€�onStartã€�onDestroy)的 Service
托管ç�€æ£åœ¨æ‰§è¡Œ onReceive() çš„ BroadcastReceiver
优先级最高,系统å�ªæœ‰åœ¨ä¸‡ä¸�å¾—å·²ï¼ˆå†…å˜æž�度匮ä¹�)时æ‰�会æ�€æ»å®ƒã€‚
��进程(Visible Process)
拥有用户��但�在��的 Activity(例如,Activity 被一个�全�的 Dialog 或 Activity 部分�挡,处于 Paused 状�)
托管�与�� Activity 绑定的 Service
优先级很高,除é�žä¸ºäº†ä¿�è¯�å‰�å�°è¿›ç¨‹çš„è¿�行,å�¦åˆ™ä¸�会被æ�€æ»ã€‚
�务进程(Service Process)
托管�通过 startService() �动且�在�行的 Service,并且该 Service �属于��或��进程类别
优先级高于��进程,但低于��进程。�行时间过长且���的�务进程也�能被回收。
缓å˜è¿›ç¨‹ï¼ˆCached Process)
ä¸�包å�«ä»»ä½•å‰�å�°ã€�å�¯è§�或æœ�务组件。通常包å�«ç”¨æˆ·å·²é€€å‡ºä½†ä»�在内å˜ä¸ï¼ˆActivity 处于 Stopped 状æ€�)的应用,以便下次快速å�¯åЍ
优先级最低,是系统内å˜ä¸�足时最先被æ�€æ»çš„对象。 缓å˜è¿›ç¨‹å†…éƒ¨ä¹Ÿæ ¹æ�® LRU(最近最少使用)ç‰ç–略进一æ¥ç»†åˆ†ä¼˜å…ˆçº§ï¼ˆå¦‚空进程ã€�å‰�一个应用进程ã€�主å±�幕进程ç‰ï¼‰ã€‚
(图示:Android 进程优先级)
Most Important (Least likely to be killed)
^
|
+-------------------------+
| Foreground Process | (Activity Resumed, Foreground Service) <- oom_adj ~ 0
+-------------------------+
|
+-------------------------+
| Visible Process | (Activity Paused but Visible) <- oom_adj ~ 100-200
+-------------------------+
|
+-------------------------+
| Service Process | (Started Service running) <- oom_adj ~ 500+
+-------------------------+
|
+-------------------------+
| Cached Process (LRU) | (Activity Stopped/Destroyed, Empty) <- oom_adj ~ 900+
+-------------------------+
|
V
Least Important (Most likely to be killed)
OOM Killer 与 oom_adj 分数
LMK(Low Memory Killer):Android å†…æ ¸ä¸çš„一个驱动或机制,负责在系统内å˜ä½ŽäºŽç‰¹å®šé˜ˆå€¼æ—¶ï¼Œæ ¹æ�®è¿›ç¨‹çš„优先级æ�€æ»è¿›ç¨‹ä»¥å›žæ”¶å†…å˜ã€‚
oom_adj(Out-of-Memory Adjustment)分数:这是 AMS(ActivityManagerService)计算并设置给æ¯�ä¸ªè¿›ç¨‹çš„ä¸€ä¸ªå…³é”®å†…æ ¸å�‚数(ä½�于 /proc/
动æ€�调整:AMS ä¼šæ ¹æ�®è¿›ç¨‹ä¸è¿�行的组件状æ€�(Activity 是å�¦å�¯è§�ã€�Service 是å�¦å‰�å�°ã€�是å�¦æœ‰ç»‘定连接ç‰ï¼‰åЍæ€�地调整进程的 oom_adj 分数。例如,当 Activity 进入å�Žå�°ï¼Œå…¶æ‰€åœ¨è¿›ç¨‹çš„ oom_adj 会å�‡é«˜ï¼›å½“ Service 调用 startForeground(),其进程的 oom_adj 会é™�低。
�解 oom_adj 的计算和影�,对于以下场景至关��:
å�Žå�°ä»»åŠ¡è®¾è®¡ï¼šé€‰æ‹©å�ˆé€‚çš„å�Žå�°æœºåˆ¶ï¼ˆå¦‚ Foreground Serviceã€�WorkManager)以ä¿�è¯�ä»»åŠ¡åœ¨ä½Žå†…å˜æƒ…况下尽å�¯èƒ½å˜æ´»
分æž�进程被æ�€ï¼šå½“应用进程æ„�外消失时,检查其被æ�€å‰�çš„ oom_adj 分数和系统内å˜çжæ€�是关键线索
优化内å˜å� 用:å‡�少应用的内å˜å� 用å�¯ä»¥é™�低整体系统内å˜åŽ‹åŠ›ï¼Œé—´æŽ¥æ��é«˜è‡ªèº«è¿›ç¨‹çš„å˜æ´»çއ
多进程应用
场景:通过在 AndroidManifest.xml ä¸ä½¿ç”¨ android:process 属性,å�¯ä»¥å°†åº”用的ä¸�å�Œç»„件(Activityã€�Serviceã€�Receiverã€�Provider)è¿�行在ä¸�å�Œçš„进程ä¸ã€‚
优点:隔离性(一个进程崩溃ä¸�å½±å“�其他进程)ã€�å�¯èƒ½ç»•过å�•进程内å˜ä¸Šé™�ï¼ˆä½†æ•´ä½“å†…å˜æ¶ˆè€—通常更高)ã€�安全性(如将æ•�感æ“�作放在独立进程)。
挑战:
IPC 开销:进程间通信必须通过 Binder(AIDL)ã€�Messengerã€�ContentProvider 或 Socket ç‰æœºåˆ¶ï¼Œå¸¦æ�¥é¢�外的性能开销和实现å¤�æ�‚度
内å˜å¢žåŠ ï¼šæ¯�个进程都有独立的虚拟机实例和è¿�行时开销,总体内å˜å� 用高于å�•进程
管ç�†å¤�æ�‚:需è¦�仔细设计进程间ä¾�èµ–ã€�生命周期å�Œæ¥ã€�æ•°æ�®å…±äº«ç‰é—®é¢˜
多进程是一ç§�架构选择,需è¦�仔细æ�ƒè¡¡å…¶å¸¦æ�¥çš„好处和æˆ�本,通常å�ªåœ¨æœ‰æ˜Žç¡®éœ€æ±‚(如稳定性隔离ã€�特殊内å˜éœ€æ±‚)时æ‰�采用。
三�Android 主线程(UI 线程):心�与瓶颈
应用进程�动时创建的第一个线程,通常被称为主线程或 UI 线程。
æ ¸å¿ƒè�Œè´£
UI 交互处�:分�和处�用户输入事件(触摸�按键)
UI 绘制:执行 Choreographer 回调,进行 Measure�Layout�Draw
组件生命周期:执行 Activityã€�Serviceã€�BroadcastReceiver ç‰ç»„件的生命周期回调方法(onCreateã€�onStartã€�onResumeã€�onReceive ç‰ï¼‰
主 Looper 任务:执行通过与主线程 Looper 关�的 Handler post 过�的 Runnable 或 Message
黄金法则:永�阻塞主线程
åŽŸå› ï¼šä¸»çº¿ç¨‹è´Ÿè´£å¤„ç�†æ‰€æœ‰ä¸Žç”¨æˆ·äº¤äº’和界é�¢æ›´æ–°çš„任务。任何耗时æ“�作(网络请求ã€�æ•°æ�®åº“读写ã€�å¤�æ�‚计算ã€�文件 IO,甚至æŸ�些有争议的é”�ç‰å¾…)如果å�‘生在主线程,都会阻æ¢å…¶å¤„ç�†æ–°çš„ UI 事件或绘制请求。
�果:
轻微:掉帧(Jank)�动画�顿�界�失去�应
严é‡�:触å�‘ ANR(Application Not Responding)对è¯�框,用户å�¯èƒ½é€‰æ‹©å¼ºåˆ¶å…³é—应用
四�Binder 线程:跨进程通信的执行者
如 Binder ç« èŠ‚æ‰€è¿°ï¼Œå½“å…¶ä»–è¿›ç¨‹ï¼ˆåŒ…æ‹¬ç³»ç»Ÿæœ�务)通过 Binder 调用当å‰�进程æ��供的æœ�务时,请求是在专门的 Binder 线程上执行的。
Binder çº¿ç¨‹æ± ï¼šæ¯�个æ��ä¾› Binder æœ�åŠ¡çš„è¿›ç¨‹ç»´æŠ¤ä¸€ä¸ªçº¿ç¨‹æ± ï¼ˆç”± libbinder å’Œå†…æ ¸é©±åŠ¨ç®¡ç�†ï¼‰ï¼Œç”¨äºŽå¹¶å�‘处ç�†ä¼ 入的 IPC 调用。默认上é™�通常是 15 个线程(主线程除外)。
执行上下文:AIDL 接å�£æ–¹æ³•的实现代ç �(或 Binder.onTransact)è¿�行在 Binder 线程上。
æ ¸å¿ƒè§„åˆ™
ç¦�æ¢è€—æ—¶æ“�作:å�Œæ ·åœ°ï¼Œä¸�能在 Binder çº¿ç¨‹ä¸æ‰§è¡Œå�¯èƒ½é˜»å¡žçš„æ“�作,å�¦åˆ™ä¼šè€—å°½çº¿ç¨‹æ± èµ„æº�,导致å�Žç»çš„ IPC 请求(包括æ�¥è‡ªç³»ç»Ÿçš„é‡�è¦�è°ƒç”¨ï¼‰æ— æ³•è¢«å�Šæ—¶å¤„ç�†ï¼Œå¼•å�‘æ»é”�或 ANR。必须将耗时任务异æ¥åŒ–
ç¦�æ¢ç›´æŽ¥ UI 更新:Binder 线程ä¸�能直接æ“�作 UI 组件。需è¦�通过 Handler å°† UI 更新任务切æ�¢å›žä¸»çº¿ç¨‹æ‰§è¡Œ
线程安全:如果 Binder 方法访问了å�¯èƒ½è¢«ä¸»çº¿ç¨‹æˆ–å…¶ä»–å�Žå�°çº¿ç¨‹å¹¶å�‘访问的共享数æ�®ï¼Œå¿…须采å�–æ£ç¡®çš„å�Œæ¥æŽªæ–½
五ã€�å�Žå�°çº¿ç¨‹ç–略:将耗时任务请出主线程
为了�守「�阻塞主线程/Binder 线程�的规则,必须将耗时任务放到��线程执行。
基本 Thread + Runnable
最基础的方å¼�,ç�µæ´»ä½†ç®¡ç�†å¤�æ�‚。需è¦�手动处ç�†çº¿ç¨‹ç”Ÿå‘½å‘¨æœŸã€�䏿–ã€�错误ã€�与主线程通信ç‰ï¼Œå®¹æ˜“出错。
ExecutorService / ThreadPoolExecutor
推è��æ–¹å¼�:æ��ä¾›çº¿ç¨‹æ± ç®¡ç�†ï¼Œå¤�用线程,é�¿å…�频ç¹�创建销æ¯�线程的开销。
ç�µæ´»æ€§ï¼šå�¯ä»¥é…�ç½®æ ¸å¿ƒçº¿ç¨‹æ•°ã€�最大线程数ã€�çº¿ç¨‹å˜æ´»æ—¶é—´ã€�任务队列类型(有界/æ— ç•Œï¼‰ã€�æ‹’ç»�ç–略。
使用:通过 Executors å·¥åŽ‚ç±»åˆ›å»ºå¸¸ç”¨ç±»åž‹çº¿ç¨‹æ± ï¼ˆnewFixedThreadPoolã€�newCachedThreadPoolã€�newSingleThreadExecutorï¼‰ï¼Œæˆ–ç›´æŽ¥æž„é€ ThreadPoolExecutor 进行精细控制。使用 submit() 或 execute() æ��交 Runnable 或 Callable 任务。
æ ¹æ�®ä»»åŠ¡ç±»åž‹ï¼ˆCPU 密集型 vs IO 密集型)å�ˆç�†é…�ç½®çº¿ç¨‹æ± å¤§å°�(CPU 密集型通常接近 CPU æ ¸å¿ƒæ•°ï¼ŒIO 密集型å�¯ä»¥æ›´å¤§ï¼‰ï¼›é€‰æ‹©å�ˆé€‚的任务队列和拒ç»�ç–略;注æ„�çº¿ç¨‹æ± çš„ç”Ÿå‘½å‘¨æœŸç®¡ç�†ï¼ˆé€‚æ—¶ shutdown())。
AsyncTask(已弃用)
已弃用,��推�使用。
IntentService(已弃用)/ JobIntentService
已弃用,建议使用 WorkManager ç‰æ›¿ä»£æ–¹æ¡ˆã€‚
Kotlin Coroutines(�程)——现代首选
轻�级:�程是�行在线程之上的��挂起和��的计算�元,比线程更轻�。�以创建大��程而�会耗尽系统资�
简化异æ¥ï¼šä½¿ç”¨ suspend 关键å—使得异æ¥ä»£ç �写起æ�¥åƒ�å�Œæ¥ä»£ç �ä¸€æ ·ç›´è§‚
结构化并�:�供了 CoroutineScope(如 viewModelScope�lifecycleScope)�管��程的生命周期,与组件生命周期绑定,自动�消,�大�少泄�风险
调度器(Dispatchers):方便地在��线程(Dispatchers.Main�Dispatchers.IO�Dispatchers.Default)之间切��程执行上下文
生æ€�:与 Jetpack 库(LiveDataã€�ViewModelã€�Room ç‰ï¼‰æ·±åº¦é›†æˆ�。是目å‰� Kotlin å¼€å�‘ Android 应用进行并å�‘编程的首选方案
RxJava / RxAndroid
å“�应å¼�编程:基于观察者模å¼�,使用强大的æ“�作符链å¼�组å�ˆã€�转æ�¢ã€�过滤异æ¥äº‹ä»¶æµ�
优点:处ç�†å¤�æ�‚异æ¥é€»è¾‘ã€�多数æ�®æº�å�ˆå¹¶ã€�背压ç‰åœºæ™¯é�žå¸¸å¼ºå¤§
缺点:å¦ä¹ 曲线较陡å³ï¼Œæ¦‚念较多(Observableã€�Operatorã€�Scheduler ç‰ï¼‰ï¼Œä»£ç �å�¯èƒ½ä¸�易ç�†è§£
å…ã€�Handlerã€�Looperã€�MessageQueue 详解:Android 线程通信的基石
这是 Android 框架内部广泛使用的线程通信和任务调度机制,尤其用于在ä¸�å�Œçº¿ç¨‹é—´å®‰å…¨åœ°ä¼ 递消æ�¯å’Œæ‰§è¡Œä»»åŠ¡ï¼ˆç‰¹åˆ«æ˜¯åˆ‡æ�¢å›žä¸»çº¿ç¨‹ï¼‰ã€‚
æ ¸å¿ƒç»„ä»¶
Message:æ�ºå¸¦å°‘é‡�æ•°æ�®ï¼ˆwhatã€�arg1ã€�arg2ã€�obj——é�¿å…�用 obj ä¼ é€’å¤§å¯¹è±¡ï¼Œè€ƒè™‘ setData(Bundle))或一个 Runnable 任务。包å�«ä¸€ä¸ª target å—æ®µæŒ‡å�‘处ç�†å®ƒçš„ Handler。
MessageQueue:æ¯�个拥有 Looper 的线程都有一个 MessageQueue。它按执行时间顺åº�å˜å‚¨å¾…处ç�†çš„ Message。当队列为空时,它会通过底层的 Linux epoll 机制高效地阻塞ç‰å¾…,直到新消æ�¯åˆ°æ�¥æˆ–超时。这是 Looper.loop() ä¸�会空耗 CPU çš„åŽŸå› ã€‚
Looper:æ¯�个线程最多å�ªèƒ½æœ‰ä¸€ä¸ª Looper(通过 ThreadLocal å˜å‚¨ï¼‰ã€‚å®ƒçš„æ ¸å¿ƒæ˜¯ loop() 方法,该方法进入一个æ»å¾ªçŽ¯ï¼Œä¸�æ–地从其 MessageQueue ä¸å�–出下一æ�¡æ¶ˆæ�¯ï¼ˆqueue.next()),如果消æ�¯ä¸�为空,则将其分å�‘给消æ�¯çš„ç›®æ ‡ Handler(msg.target.dispatchMessage(msg))。
Handler:
创建:在哪个线程创建 Handler 实例,它默认就与该线程的 Looper 关�(除�显�指定 Looper)
å�‘é€�/å�‘布:æ��ä¾› post(Runnable)ã€�postDelayed()ã€�sendMessage()ã€�sendMessageDelayed()ã€�obtainMessage().sendToTarget() ç‰æ–¹æ³•,将 Runnable 包装æˆ� Message 或直接将 Message æ”¾å…¥ç›®æ ‡ Looper çš„ MessageQueue ä¸
处ç�†ï¼šdispatchMessage(Message msg) 方法负责执行。如果 Message 有关è�”çš„ Runnable,则执行 Runnableï¼›å�¦åˆ™ï¼Œå¦‚æžœ Handler åˆ›å»ºæ—¶ä¼ å…¥äº† Callback 接å�£ï¼Œåˆ™è°ƒç”¨ callback.handleMessage();最å�Žï¼Œå¦‚æžœå‰�两者都没有,则调用 Handler å�类覆写的 handleMessage(Message msg) 方法。执行å�‘生在与 Handler å…³è�”çš„ Looper 所在的线程上
ThreadLocal 的作用:Looper 使用 ThreadLocal
�典用途
å�线程 → 主线程更新 UI:在å�线程创建 new Handler(Looper.getMainLooper()),然å�Žé€šè¿‡æ¤ Handler post 一个更新 UI çš„ Runnable。
创建自定义工作线程:
class WorkerThread extends Thread {
public Handler mHandler; // Handler for this worker thread
@Override
public void run() {
Looper.prepare(); // Associate a Looper with this thread
// Handler created here is associated with the new Looper
mHandler = new Handler(Looper.myLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
// Process messages received on this worker thread
Log.d("WorkerThread", "Processing message: " + msg.what);
}
};
Looper.loop(); // Start the message loop, blocks until Looper.quit()
Log.d("WorkerThread", "Looper finished.");
}
}
// Usage:
WorkerThread worker = new WorkerThread();
worker.start();
// Wait until handler is created (use CountDownLatch or similar for safety)
// ...
// Send messages from other threads to the worker thread's handler
worker.mHandler.obtainMessage(MSG_DO_WORK, someData).sendToTarget();
// ...
// To stop the worker thread's looper:
// worker.mHandler.getLooper().quitSafely(); // Or quit()
HandlerThread:Android �供的一个便利类,�装了上述创建带 Looper 的工作线程的逻辑。
常�陷阱
å†…å˜æ³„æ¼�:在 Activity/Fragment ä¸ä½¿ç”¨é�žé�™æ€�内部类 Handler,会导致 Handler éš�å¼�æŒ�有外部类引用。如果 Handler å�‘é€�了延迟消æ�¯ï¼Œå�³ä½¿ Activity 销æ¯�,消æ�¯ä»�在队列ä¸ï¼ŒHandler å’Œ Activity éƒ½æ— æ³•è¢«å›žæ”¶ã€‚è§£å†³æ–¹æ¡ˆï¼šä½¿ç”¨é�™æ€�内部类 + WeakReference
主线程 Looper 阻塞:在主线程 Handler çš„ handleMessage 或 Runnable.run 䏿‰§è¡Œè€—æ—¶æ“�作
消�队列过载:过度��大�消��能导致处�延迟
七ã€�高级å�Œæ¥ä¸Žçº¿ç¨‹å®‰å…¨
当多个线程访问共享的å�¯å�˜æ•°æ�®æ—¶ï¼Œå¿…须使用å�Œæ¥æœºåˆ¶æ�¥ä¿�è¯�æ•°æ�®çš„原å�性(Atomicity)ã€�å�¯è§�性(Visibility) 和有åº�性(Ordering),防æ¢å‡ºçŽ°æ•°æ�®ç«žäº‰å’Œä¸�一致状æ€�。
æ ¸å¿ƒæ¦‚å¿µ
原å�性:一个æ“�作或者多个æ“�作è¦�么全部执行并且执行的过程ä¸�ä¼šè¢«ä»»ä½•å› ç´ æ‰“æ–,è¦�么就都ä¸�执行
��性:当一个线程修改了共享��的值,其他线程能够立�得知这个修改
有åº�性:程åº�执行的顺åº�按照代ç �的先å�Žé¡ºåº�执行(编译器和处ç�†å™¨å�¯èƒ½ä¼šè¿›è¡ŒæŒ‡ä»¤é‡�排优化,需è¦�å�Œæ¥æœºåˆ¶æ�¥ä¿�è¯�特定情况下的有åº�性)
å�Œæ¥åŽŸè¯ï¼ˆPrimitives)选择与应用
synchronized(内置�)
优点:使用简�,�易出错(自动释放�)
缺点:功能相对有é™�——é”�是ä¸�å�¯ä¸æ–的;ä¸�支æŒ�公平性;一个é”�å�ªèƒ½å…³è�”一个æ�¡ä»¶ç‰å¾…队列。适用于简å�•ã€�低竞争的场景
volatile
作用:ä¿�è¯�被修饰å�˜é‡�çš„å�¯è§�性;ç¦�æ¢æŒ‡ä»¤é‡�排åº�优化(部分ä¿�è¯�有åº�性)
å±€é™�:ä¸�ä¿�è¯�原å�性。例如 volatile int i; i++; ä¸�是原å�æ“�作
适用:主è¦�用于状æ€�æ ‡å¿—ä½�(如 volatile boolean flag = false;)或确ä¿�å�•次读写æ“�作的å�¯è§�性。ä¸�能替代é”�用于ä¿�护å¤�å�ˆæ“�作
java.util.concurrent.locks.Lock(如 ReentrantLock)
优点:功能更强——å�¯ä¸æ–é”�(lockInterruptibly);å�¯è¶…æ—¶é”�(tryLock);å�¯å®žçް公平/é�žå…¬å¹³é”�ï¼›å�¯å…³è�”多个 Condition 对象(用于实现更å¤�æ�‚çš„ç‰å¾…/通知模å¼�)
缺点:必须手动在 finally å�—ä¸é‡Šæ”¾é”�(unlock()),å�¦åˆ™å�¯èƒ½å¯¼è‡´æ»é”�
适用:需è¦�æ›´ç�µæ´»çš„é”�控制ã€�å�¯ä¸æ–性ã€�公平性或多个ç‰å¾…æ�¡ä»¶çš„场景。性能在低竞争下与 synchronized 类似,高竞争下通常更好(但具体å�–决于实现和平å�°ï¼‰
ReadWriteLock(如 ReentrantReadWriteLock)
场景:读多写少的共享数�。�许多个读线程�时访问,但写�作是互斥的
优点:显著�高读�作的并�性
注æ„�:实现比 ReentrantLock æ›´å¤�æ�‚,需è¦�æ£ç¡®ä½¿ç”¨è¯»é”�(readLock())和写é”�(writeLock())
java.util.concurrent.atomic.*
场景:对å�•个å�˜é‡�(计数器ã€�状æ€�æ ‡å¿—ï¼‰è¿›è¡ŒåŽŸå�æ›´æ–°
原ç�†ï¼šåˆ©ç”¨ CPU æ��供的 CAS(Compare-and-Swap)原å�æŒ‡ä»¤å®žçŽ°ï¼Œæ— é”�(Lock-Free),效率高
优点:比使用�更轻��性能更好
å±€é™�:å�ªèƒ½ä¿�è¯�å�•个å�˜é‡�的原å�性,ä¸�能ä¿�è¯�å¤�å�ˆæ“�作的原å�性
CountDownLatch
场景:一个线程需è¦�ç‰å¾…一个或多个其他线程完æˆ�æŸ�些æ“�作å�Žæ‰�èƒ½ç»§ç»æ‰§è¡Œã€‚例如,主线程ç‰å¾…多个åˆ�始化å�任务完æˆ�
CyclicBarrier
场景:多个线程需è¦�相互ç‰å¾…,直到所有线程都到达一个「å±�障点ã€�,然å�Žæ‰�èƒ½ä¸€èµ·ç»§ç»æ‰§è¡Œä¸‹ä¸€æ¥ã€‚å�¯ä»¥é‡�用。例如,并行计算ä¸ï¼Œå�„阶段需è¦�ç‰å¾…所有线程完æˆ�
Semaphore(信��)
场景:控制å�Œæ—¶è®¿é—®æŸ�个特定资æº�(如数æ�®åº“è¿žæŽ¥æ± ã€�网络连接数)的线程数é‡�
BlockingQueue
场景:生产者-消费者模å¼�。解耦生产者线程和消费者线程,自带å�Œæ¥å’Œé˜»å¡žåŠŸèƒ½
线程安全最佳实践
优先考虑ä¸�å�¯å�˜æ€§ï¼ˆImmutability):如果共享数æ�®æ˜¯ä¸�å�¯å�˜çš„(创建å�Žçжæ€�ä¸�å†�改å�˜ï¼‰ï¼Œåˆ™å¤©ç”Ÿçº¿ç¨‹å®‰å…¨ï¼Œæ— 需å�Œæ¥
缩å°�å�Œæ¥èŒƒå›´ï¼šå°½é‡�å‡�å°�é”�ä¿�护的代ç �å�—范围,å�ªä¿�护必è¦�的临界区,以æ��高并å�‘性
é”�顺åº�:如果需è¦�获å�–多个é”�,确ä¿�所有线程都以相å�Œçš„固定顺åº�获å�–é”�,以é�¿å…�æ»é”�
使用并å�‘容器:java.util.concurrent 包æ��供了线程安全的集å�ˆç±»ï¼ˆå¦‚ ConcurrentHashMapã€�CopyOnWriteArrayList),通常比手动å�Œæ¥ HashMap/ArrayList 更高效ã€�更安全
é�¿å…�æŒ�有é”�时执行耗时æ“�作或调用外部方法:防æ¢é•¿æ—¶é—´å� 用é”�
八�ANR(Application Not Responding)深度分�
ANR 是 Android 䏿Œ‡ç¤ºåº”用严é‡�æ— å“�应的信å�·ï¼Œæ˜¯å¿…须能够熟练诊æ–和解决的问题。
触��件回顾
输入事件超时:5 秒内未处�完输入事件(触摸�按键)
å¹¿æ’æŽ¥æ”¶å™¨è¶…æ—¶ï¼šonReceive() 执行时间过长(å‰�å�°å¹¿æ’通常 10 秒,å�Žå�°å¹¿æ’å�¯èƒ½ 60 秒)
Service 超时:onCreate()ã€�onStartCommand()ã€�onBind() ç‰å…³é”®æ–¹æ³•执行时间过长(å‰�å�°æœ�务 20 秒,å�Žå�°æœ�务å�¯èƒ½ 200 秒)
系统性分æž�æ¥éª¤
1. 获� ANR Trace 文件
这是最��的��。�以从 /data/anr/traces.txt(需� root 或通过 adb bugreport),或 Google Play Console ��获�。
2. 识别 ANR 类型与时间
查看 Trace 文件开头的摘�信�,确认是哪�类型的 ANR(Input timeout�Broadcast timeout�Service timeout)以��生时间。
3. 主线程(“main�)状�分�
这是分æž�çš„æ ¸å¿ƒï¼� 仔细检查「mainã€�çº¿ç¨‹çš„å †æ ˆä¿¡æ�¯ï¼š
阻塞点:它最终�在了哪个方法调用上?
IO æ“�作? 是å�¦åœ¨è¿›è¡Œæ–‡ä»¶è¯»å†™ã€�网络请求ã€�æ•°æ�®åº“æ“�ä½œï¼ˆçœ‹å †æ ˆä¸æ˜¯å�¦æœ‰nativePollOnceã€�socketReadã€�FileInputStream.readã€�SQLiteDatabase 相关调用)?
CPU 密集计算? å †æ ˆæ˜¯å�¦æ˜¾ç¤ºæ£åœ¨æ‰§è¡Œå¤�æ�‚的计算逻辑?
é”�ç‰å¾…? 是å�¦å�¡åœ¨ monitor wait 或 LockSupport.park / Object.wait ç‰å¾…é”�?Trace ä¸é€šå¸¸ä¼šæ˜¾ç¤ºã€Œwaiting to lock <0x…>(a …)ã€�以å�Šã€Œheld by threadid=ã€�
Binder 调用? 是å�¦å�¡åœ¨ BinderProxy.transactNative 或 binder_thread_read?如果是,看调用的是哪个æœ�åŠ¡ï¼ˆé€šå¸¸èƒ½ä»Žå †æ ˆæˆ– Binder 相关信æ�¯çœ‹å‡ºï¼‰ã€‚å¦‚æžœç›®æ ‡æ˜¯ç³»ç»Ÿæœ�务,需è¦�怀疑 SystemServer 是å�¦ç¼“慢或æ»é”�
GC? å †æ ˆæ˜¯å�¦æ˜¾ç¤ºæ£åœ¨è¿›è¡Œ GC 相关æ“�作?(虽然 GC 本身引起的 ANR 相对少è§�,但长 GC æš‚å�œå�¯èƒ½åŠ å‰§å…¶ä»–è¶…æ—¶ï¼‰
4. 分���有者线程
如果主线程在ç‰å¾…é”�ï¼Œæ ¹æ�® Trace 䏿��供的æŒ�有者线程 ID(tidï¼‰ï¼Œæ‰¾åˆ°è¯¥çº¿ç¨‹çš„å †æ ˆã€‚åˆ†æž�该线程为什么长时间æŒ�有é”�?它是å�¦ä¹Ÿåœ¨è¿›è¡Œ IOã€�计算ã€�ç‰å¾…å…¶ä»–é”�(形æˆ�æ»é”�链)ã€�或进行 Binder 调用?
5. 分� Binder 线程
检查所有�为「Binder:
6. 检查其他线程
æµ�览其他å�Žå�°çº¿ç¨‹çš„å †æ ˆï¼Œçœ‹æ˜¯å�¦æœ‰å¼‚常活动,如å�‚与æ»é”�ã€�消耗过多 CPU 资æº�导致主线程饥饿ç‰ã€‚
7. CPU 负载分�
查看 Trace 文件末尾的 CPU 负载信æ�¯ï¼ˆåˆ† User/Kernel/IOwait/IRQ/SoftIRQ)。高 User% å�¯èƒ½æ„�味 CPU 密集计算。高 IOwait% æ„�味ç£�盘或网络 IO 瓶颈。高 Kernel% å�¯èƒ½ä¸Žé©±åŠ¨æˆ–ç³»ç»Ÿè°ƒç”¨æœ‰å…³ã€‚æ£€æŸ¥ ANR å�‘生时主线程所在 CPU æ ¸å¿ƒæ˜¯å�¦ç¹�忙。
8. �信�分�
仔细阅读 Trace 文件ä¸çš„ Locks 部分,它会列出所有å�‘生争用的é”�以å�Šç‰å¾…å’ŒæŒ�有线程的信æ�¯ï¼Œæ˜¯åˆ†æž�æ»é”�的关键。
9. 结� Systrace/Perfetto
强烈推�� 如果能在�现 ANR 场景时抓� Trace,将�大简化分�。Perfetto/Systrace �以:
å�¯è§†åŒ–线程状æ€�:清晰看到主线程在 ANR å�‘生å‰�长时间处于 Runnable(ç‰å¾… CPU 调度)还是 Running(执行代ç �)还是 Sleeping/Blocked 状æ€�
定ä½�耗时代ç �:结å�ˆ CPU Time Profiling,直接定ä½�到主线程或é”�æŒ�有者线程ä¸è€—时最长的方法
分æž�é”�竞争:直观展示é”�çš„æŒ�有和ç‰å¾…关系
分æž� Binder 调用:显示 Binder äº‹åŠ¡çš„è€—æ—¶å’Œç›®æ ‡
关�系统事件:查看 GC�系统�务活动是�与 ANR 相关
ä¹�ã€�结论:掌控并å�‘,驾é©å“�应
Android 的进程和线程模型是其并å�‘架构的基础,直接关系到应用的资æº�消耗ã€�稳定性与用户体验。从 Linux 的底层机制,到 Android 系统通过 AMS å’Œ oom_adj 对进程生命周期的精细管ç�†ï¼Œå†�到应用内部主线程ã€�Binder 线程ã€�å�Žå�°çº¿ç¨‹çš„è�Œè´£åˆ’分与å��å�Œï¼Œä»¥å�Š Handler/Looper 机制和å�„ç§�å�Œæ¥åŽŸè¯çš„应用,共å�Œæž„æˆ�了这个å¤�æ�‚而é‡�è¦�的体系。
Android 专家必须超越基础的线程使用,深刻ç�†è§£è¿›ç¨‹ä¼˜å…ˆçº§ä¸Ž LMK 的交互,掌æ�¡ä¸»çº¿ç¨‹çš„æ€§èƒ½çº¢çº¿ï¼Œç†Ÿæ‚‰ Binder çº¿ç¨‹æ± çš„è¿�ä½œï¼Œèƒ½å¤Ÿæ ¹æ�®åœºæ™¯é€‰æ‹©æœ€ä¼˜çš„å�Žå�°å¹¶å�‘ç–略(如 ExecutorServiceã€�Coroutines),精通 Handler 机制的内部原ç�†ä¸Žåº”用,并能够熟练è¿�用å�„ç§�高级å�Œæ¥å·¥å…·è§£å†³å¤�æ�‚的线程安全问题。更é‡�è¦�的是,é�¢å¯¹ ANR 这一顽疾,能够è¿�用系统性的方法,结å�ˆ ANR Trace å’Œ Perfetto ç‰å·¥å…·ï¼ŒæŠ½ä¸�剥茧,定ä½�并解决从应用代ç �到系统æœ�务交互ä¸å�¯èƒ½å˜åœ¨çš„å�„ç§�性能瓶颈和æ»é”�问题。
对进程与线程模型的深度掌控,ä¸�仅是é�¿å…� ANR 的技术ä¿�障,更是实现高性能ã€�高并å�‘ã€�高稳定性应用,从而æ��ä¾›å�“è¶Šç”¨æˆ·ä½“éªŒçš„æ ¸å¿ƒèƒ½åŠ›ã€‚
延伸阅读
返回对应专题:Android Framework
Android Binder 原�:从驱动通信到 AIDL 调用链路/)
Android Framework 系统�务:AMS�WMS 与应用进程交互模型
Android ContentProvider 原�:URI 路由�跨进程访问与��控制
Android ��系统原�:�行时���拦截链路与安全边界