HandlerThread实现原理
HandlerThread 继承自 Thread 类,因此本质上它就是一个线程。与普通 Thread 的主要区别在于,HandlerThread 不仅创建了一个线程,还同时建立了消息队列,拥有自己的 Looper。这使得我们可以在该线程内部进行消息的分发和处理,并且对外提供了获取其 Looper 的 get 方法。
HandlerThread 内置 Looper 的特性,使其能够通过消息队列机制实现线程的复用,从而节省系统资源开销。这一特性既是它的优点,也是其潜在缺点:所有任务都将以队列形式依次执行,一旦队列中某个任务耗时过长,就会导致后续所有任务的处理延迟。
HandlerThread 使用
HandlerThread 使用流程图
下面是使用 HandlerThread 的典型流程,展示了从创建到任务执行的完整过程:
子线程Handler MessageQueue HandlerThread 主线程 子线程Handler MessageQueue HandlerThread 主线程 #mermaid-svg-1gqDRcz272ODlL9L{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1gqDRcz272ODlL9L .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1gqDRcz272ODlL9L .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1gqDRcz272ODlL9L .error-icon{fill:#552222;}#mermaid-svg-1gqDRcz272ODlL9L .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1gqDRcz272ODlL9L .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1gqDRcz272ODlL9L .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1gqDRcz272ODlL9L .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1gqDRcz272ODlL9L .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1gqDRcz272ODlL9L .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1gqDRcz272ODlL9L .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1gqDRcz272ODlL9L .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1gqDRcz272ODlL9L .marker.cross{stroke:#333333;}#mermaid-svg-1gqDRcz272ODlL9L svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1gqDRcz272ODlL9L p{margin:0;}#mermaid-svg-1gqDRcz272ODlL9L .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-1gqDRcz272ODlL9L text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-1gqDRcz272ODlL9L .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-1gqDRcz272ODlL9L .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-1gqDRcz272ODlL9L .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-1gqDRcz272ODlL9L .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-1gqDRcz272ODlL9L #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-1gqDRcz272ODlL9L .sequenceNumber{fill:white;}#mermaid-svg-1gqDRcz272ODlL9L #sequencenumber{fill:#333;}#mermaid-svg-1gqDRcz272ODlL9L #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-1gqDRcz272ODlL9L .messageText{fill:#333;stroke:none;}#mermaid-svg-1gqDRcz272ODlL9L .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-1gqDRcz272ODlL9L .labelText,#mermaid-svg-1gqDRcz272ODlL9L .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-1gqDRcz272ODlL9L .loopText,#mermaid-svg-1gqDRcz272ODlL9L .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-1gqDRcz272ODlL9L .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-1gqDRcz272ODlL9L .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-1gqDRcz272ODlL9L .noteText,#mermaid-svg-1gqDRcz272ODlL9L .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-1gqDRcz272ODlL9L .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-1gqDRcz272ODlL9L .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-1gqDRcz272ODlL9L .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-1gqDRcz272ODlL9L .actorPopupMenu{position:absolute;}#mermaid-svg-1gqDRcz272ODlL9L .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-1gqDRcz272ODlL9L .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-1gqDRcz272ODlL9L .actor-man circle,#mermaid-svg-1gqDRcz272ODlL9L line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-1gqDRcz272ODlL9L :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 执行 run() 方法 new HandlerThread("name")start()Looper.prepare()创建 MessageQueueLooper.loop()Looper 准备完成getLooper()返回 Loopernew Handler(looper, callback)sendMessage(msg)消息入队分发消息handleMessage(msg)执行任务(在子线程)可选:通过UI Handler更新UI
流程说明:
- 初始化阶段:主线程创建并启动 HandlerThread
- Looper 准备:HandlerThread 内部创建 Looper 和 MessageQueue
- Handler 创建:主线程获取 Looper 并创建子线程 Handler
- 消息发送:主线程通过 Handler 发送消息到子线程
- 任务执行:子线程处理消息并执行相应任务
java
public class HandlerThreadActivity extends AppCompatActivity {
private Button mButton;
private HandlerThread mHandlerThread;
private Handler mUiHandler;
private Handler mChildHandler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler);
initView();
mHandlerThread = new HandlerThread("HandlerThread");
mHandlerThread.start();
mUiHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
if (msg.what == 2) {
mButton.setText("子线程更新");
}
return false;
}
});
mChildHandler = new Handler(mHandlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
if (msg.what == 1) {
try {
//子线程模拟延迟处理
Thread.sleep(2000);
mUiHandler.sendEmptyMessage(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return false;
}
});
}
public void initView() {
mButton = findViewById(R.id.btn_show);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mChildHandler.sendEmptyMessage(1);
}
});
}
}
源码分析
java
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
private @Nullable Handler mHandler;
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
protected void onLooperPrepared() {
}
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
// 通知取 Looper 的线程,此时 Looper 已经创建好了
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
public Looper getLooper() {
if (!isAlive()) {
return null;
}
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
// 如果新线程还未创建 Looper,则等待
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
@NonNull
public Handler getThreadHandler() {
if (mHandler == null) {
mHandler = new Handler(getLooper());
}
return mHandler;
}
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
public int getThreadId() {
return mTid;
}
}
源码的核心逻辑很简单:在 run() 方法中执行 Looper.prepare() 和 Looper.loop(),从而构建一个消息循环系统。外部可以通过 getLooper() 方法获取到这个 Looper。
总结如下:
- HandlerThread 是一个自带 Looper 的线程,因此只能作为子线程使用。
- HandlerThread 必须配合 Handler 使用。线程中具体执行的任务需要在 Handler 的 callback 中定义,因为其自身的
run()方法已被固定实现。 - 子线程的 Handler 与 HandlerThread 之间的关联,是通过在构造子线程的 Handler 时传入 HandlerThread 的 Looper 来实现的。因此,在此之前必须先调用
mHandlerThread.start()启动线程,让run()方法运行起来,Looper 才能被创建。
HandlerThread 生命周期状态图
最后,通过状态图展示 HandlerThread 的完整生命周期:
#mermaid-svg-9XASXn7y8ROe2ug7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-9XASXn7y8ROe2ug7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-9XASXn7y8ROe2ug7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-9XASXn7y8ROe2ug7 .error-icon{fill:#552222;}#mermaid-svg-9XASXn7y8ROe2ug7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9XASXn7y8ROe2ug7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-9XASXn7y8ROe2ug7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9XASXn7y8ROe2ug7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9XASXn7y8ROe2ug7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-9XASXn7y8ROe2ug7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9XASXn7y8ROe2ug7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9XASXn7y8ROe2ug7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9XASXn7y8ROe2ug7 .marker.cross{stroke:#333333;}#mermaid-svg-9XASXn7y8ROe2ug7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9XASXn7y8ROe2ug7 p{margin:0;}#mermaid-svg-9XASXn7y8ROe2ug7 defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-9XASXn7y8ROe2ug7 g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-9XASXn7y8ROe2ug7 g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-9XASXn7y8ROe2ug7 g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-9XASXn7y8ROe2ug7 g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-9XASXn7y8ROe2ug7 g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-9XASXn7y8ROe2ug7 .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-9XASXn7y8ROe2ug7 .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-9XASXn7y8ROe2ug7 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-9XASXn7y8ROe2ug7 .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-9XASXn7y8ROe2ug7 .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-9XASXn7y8ROe2ug7 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-9XASXn7y8ROe2ug7 .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-9XASXn7y8ROe2ug7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9XASXn7y8ROe2ug7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-9XASXn7y8ROe2ug7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9XASXn7y8ROe2ug7 .edgeLabel .label text{fill:#333;}#mermaid-svg-9XASXn7y8ROe2ug7 .label div .edgeLabel{color:#333;}#mermaid-svg-9XASXn7y8ROe2ug7 .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-9XASXn7y8ROe2ug7 .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-9XASXn7y8ROe2ug7 .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-9XASXn7y8ROe2ug7 .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-9XASXn7y8ROe2ug7 .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-9XASXn7y8ROe2ug7 .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9XASXn7y8ROe2ug7 .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9XASXn7y8ROe2ug7 #statediagram-barbEnd{fill:#333333;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9XASXn7y8ROe2ug7 .cluster-label,#mermaid-svg-9XASXn7y8ROe2ug7 .nodeLabel{color:#131300;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-9XASXn7y8ROe2ug7 .note-edge{stroke-dasharray:5;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagram-note text{fill:black;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagram-note .nodeLabel{color:black;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagram .edgeLabel{color:red;}#mermaid-svg-9XASXn7y8ROe2ug7 #dependencyStart,#mermaid-svg-9XASXn7y8ROe2ug7 #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-9XASXn7y8ROe2ug7 .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-9XASXn7y8ROe2ug7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} start()
run()开始
Looper.prepare()完成
Looper.loop()
有消息到达
处理完成
quit()/quitSafely()
新建状态
运行状态
Looper准备中
Looper运行中
消息循环中
消息处理
终止状态
线程对象已创建
但尚未启动
getLooper()可返回
Looper对象
线程持续运行
等待消息处理
状态说明:
- 新建状态:HandlerThread 对象已创建但未启动
- 运行状态:线程已启动,开始执行 run() 方法
- Looper准备中:正在执行 Looper.prepare(),Looper 尚未就绪
- Looper运行中:Looper 已创建,可通过 getLooper() 获取
- 消息循环中:Looper.loop() 正在运行,等待消息处理
- 消息处理:正在处理具体的消息任务
- 终止状态:调用了 quit() 或 quitSafely(),线程结束
HandlerThread 架构图
为了更好地理解 HandlerThread 的工作原理,下面是一个架构图展示了其核心组件和消息处理流程:
#mermaid-svg-eq1Pg3qPrr03Ygmb{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-eq1Pg3qPrr03Ygmb .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-eq1Pg3qPrr03Ygmb .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-eq1Pg3qPrr03Ygmb .error-icon{fill:#552222;}#mermaid-svg-eq1Pg3qPrr03Ygmb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-eq1Pg3qPrr03Ygmb .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-eq1Pg3qPrr03Ygmb .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-eq1Pg3qPrr03Ygmb .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-eq1Pg3qPrr03Ygmb .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-eq1Pg3qPrr03Ygmb .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-eq1Pg3qPrr03Ygmb .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-eq1Pg3qPrr03Ygmb .marker{fill:#333333;stroke:#333333;}#mermaid-svg-eq1Pg3qPrr03Ygmb .marker.cross{stroke:#333333;}#mermaid-svg-eq1Pg3qPrr03Ygmb svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-eq1Pg3qPrr03Ygmb p{margin:0;}#mermaid-svg-eq1Pg3qPrr03Ygmb .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-eq1Pg3qPrr03Ygmb .cluster-label text{fill:#333;}#mermaid-svg-eq1Pg3qPrr03Ygmb .cluster-label span{color:#333;}#mermaid-svg-eq1Pg3qPrr03Ygmb .cluster-label span p{background-color:transparent;}#mermaid-svg-eq1Pg3qPrr03Ygmb .label text,#mermaid-svg-eq1Pg3qPrr03Ygmb span{fill:#333;color:#333;}#mermaid-svg-eq1Pg3qPrr03Ygmb .node rect,#mermaid-svg-eq1Pg3qPrr03Ygmb .node circle,#mermaid-svg-eq1Pg3qPrr03Ygmb .node ellipse,#mermaid-svg-eq1Pg3qPrr03Ygmb .node polygon,#mermaid-svg-eq1Pg3qPrr03Ygmb .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-eq1Pg3qPrr03Ygmb .rough-node .label text,#mermaid-svg-eq1Pg3qPrr03Ygmb .node .label text,#mermaid-svg-eq1Pg3qPrr03Ygmb .image-shape .label,#mermaid-svg-eq1Pg3qPrr03Ygmb .icon-shape .label{text-anchor:middle;}#mermaid-svg-eq1Pg3qPrr03Ygmb .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-eq1Pg3qPrr03Ygmb .rough-node .label,#mermaid-svg-eq1Pg3qPrr03Ygmb .node .label,#mermaid-svg-eq1Pg3qPrr03Ygmb .image-shape .label,#mermaid-svg-eq1Pg3qPrr03Ygmb .icon-shape .label{text-align:center;}#mermaid-svg-eq1Pg3qPrr03Ygmb .node.clickable{cursor:pointer;}#mermaid-svg-eq1Pg3qPrr03Ygmb .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-eq1Pg3qPrr03Ygmb .arrowheadPath{fill:#333333;}#mermaid-svg-eq1Pg3qPrr03Ygmb .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-eq1Pg3qPrr03Ygmb .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-eq1Pg3qPrr03Ygmb .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-eq1Pg3qPrr03Ygmb .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-eq1Pg3qPrr03Ygmb .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-eq1Pg3qPrr03Ygmb .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-eq1Pg3qPrr03Ygmb .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-eq1Pg3qPrr03Ygmb .cluster text{fill:#333;}#mermaid-svg-eq1Pg3qPrr03Ygmb .cluster span{color:#333;}#mermaid-svg-eq1Pg3qPrr03Ygmb div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-eq1Pg3qPrr03Ygmb .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-eq1Pg3qPrr03Ygmb rect.text{fill:none;stroke-width:0;}#mermaid-svg-eq1Pg3qPrr03Ygmb .icon-shape,#mermaid-svg-eq1Pg3qPrr03Ygmb .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-eq1Pg3qPrr03Ygmb .icon-shape p,#mermaid-svg-eq1Pg3qPrr03Ygmb .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-eq1Pg3qPrr03Ygmb .icon-shape .label rect,#mermaid-svg-eq1Pg3qPrr03Ygmb .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-eq1Pg3qPrr03Ygmb .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-eq1Pg3qPrr03Ygmb .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-eq1Pg3qPrr03Ygmb :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 主线程 (Main Thread)
创建 HandlerThread
HandlerThread.start()
子线程执行 run()
Looper.prepare()
创建 Looper 和 MessageQueue
Looper.loop()
消息循环开始
主线程获取 Looper
getLooper()
创建 Handler (传入 Looper)
Handler.sendMessage()
消息进入 MessageQueue
Looper 分发消息
Handler.handleMessage()
在子线程执行任务
图例说明:
- 蓝色框:主线程操作
- 绿色框:HandlerThread 内部操作
- 橙色框:消息处理流程
- 虚线箭头:跨线程通信