Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit cc8017c

Browse files
author
tao
committed
2 parents ca4efaa + 1d10973 commit cc8017c

File tree

10 files changed

+1321
-255
lines changed

10 files changed

+1321
-255
lines changed

Android/ActivityThread.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
### ActivityThread分析
2+
3+
#### 他是个啥
4+
5+
首先问大家一个问题,一个Activity的生命周期方法有哪些?
6+
7+
不多说,上图:
8+
9+
![Activity生命周期](../img/activity_lifecycle.png)
10+
11+
我们熟悉的一个Java应用,不应该是从
12+
13+
```java
14+
public static void main(String args[]) {
15+
....
16+
}
17+
```
18+
19+
开始吗?那么我们这里的main方法那里去了?答案就在这个ActivityThread里面。
20+
21+
#### 代码分析
22+
23+
这个哥们在哪里呢?
24+
25+
`$ANDROID_BASE/frameworks/base/core/java/android/app/ActivityThread.java`
26+
27+
28+
29+
我们在这个类里面,可以发现他的main方法:
30+
31+
```java
32+
public static void main(String[] args) {
33+
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
34+
35+
// Install selective syscall interception
36+
AndroidOs.install();
37+
38+
// CloseGuard defaults to true and can be quite spammy. We
39+
// disable it here, but selectively enable it later (via
40+
// StrictMode) on debug builds, but using DropBox, not logs.
41+
CloseGuard.setEnabled(false);
42+
43+
Environment.initForCurrentUser();
44+
45+
// Make sure TrustedCertificateStore looks in the right place for CA certificates
46+
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
47+
TrustedCertificateStore.setDefaultUserDirectory(configDir);
48+
49+
Process.setArgV0("<pre-initialized>");
50+
// 这里调用了Looper的prepare方法
51+
Looper.prepareMainLooper();
52+
53+
// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
54+
// It will be in the format "seq=114"
55+
long startSeq = 0;
56+
if (args != null) {
57+
for (int i = args.length - 1; i >= 0; --i) {
58+
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
59+
startSeq = Long.parseLong(
60+
args[i].substring(PROC_START_SEQ_IDENT.length()));
61+
}
62+
}
63+
}
64+
// 创建一个ActivityThread实例
65+
ActivityThread thread = new ActivityThread();
66+
thread.attach(false, startSeq);
67+
68+
if (sMainThreadHandler == null) {
69+
// 获取 Handler
70+
sMainThreadHandler = thread.getHandler();
71+
}
72+
73+
if (false) {
74+
75+
Looper.myLooper().setMessageLogging(new
76+
LogPrinter(Log.DEBUG, "ActivityThread"));
77+
}
78+
79+
// End of event ActivityThreadMain.
80+
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
81+
// 可以开始处理消息了
82+
Looper.loop();
83+
84+
throw new RuntimeException("Main thread loop unexpectedly exited");
85+
}
86+
```
87+
88+
比较一下这个代码和我们前文[Android Looper的分析](Android/LooperHandler.md)里面的MyLooperThread例子就可以知道,架构是一样的。但是这里有点小小的区别:
89+
90+
:arrow_right:`prepareMainLooper()``prepare()`
91+
92+
:arrow_right:`Handler`不同
93+
94+
来看第一个问题:
95+
96+
`prepareMainLooper()`和普通的`prepare()`有什么区别?
97+
98+
不多说,直接看代码:
99+
100+
```java
101+
// Looper.java
102+
public static void prepareMainLooper() {
103+
prepare(false); // 还是调用了普通版本的prepare方法, 参数false表示不允许线程退出
104+
synchronized (Looper.class) {
105+
if (sMainLooper != null) {
106+
throw new IllegalStateException("The main Looper has already been prepared.");
107+
}
108+
sMainLooper = myLooper(); // 区分开普通线程的Looper和主线程的Looper
109+
}
110+
}
111+
```
112+
113+
到此应该就很明显了。本质上没啥区别,只是Google玩了一下,巧妙的区分开普通线程和主线程的Looper而已。
114+
115+
那我们来看第二个问题:
116+
117+
`sMainThreadHandler`当ActivityThread创建的时候,可以发现,它还创建了一个这个东西:
118+
119+
```java
120+
final H mH = new H();
121+
```
122+
123+
那么这 H 是个啥?
124+
125+
```java
126+
class H extends Handler{
127+
...
128+
}
129+
```
130+
131+
真相大白!那么在这个里面,我们所谓的UI线程的Handler,就是他了。它的`handleMessage`方法比较复杂,有机会我们再行分析。

0 commit comments

Comments
 (0)