參考一篇文章:
http://blog.csdn.net/Android_Tutor/archive/2010/08/24/5834246.aspx
啟示:
- 向Handler post一個(gè)Runnable對(duì)象的時(shí)候,并沒(méi)有開(kāi)啟一個(gè)新的線程,只是將這個(gè)Runnable對(duì)象丟進(jìn)message queue,處理的時(shí)候直接調(diào)用run()方法,參見(jiàn)Handler.java
1 private final void handleCallback(Message message) {
2 message.callback.run();
3 }
- 一個(gè)應(yīng)用在第一次運(yùn)行的時(shí)候,確切的說(shuō)在啟動(dòng)一個(gè)activity的時(shí)候,Dalvik會(huì)為這個(gè)應(yīng)用創(chuàng)建一個(gè)進(jìn)程。參見(jiàn)ActivityThread.java
1 private final void startProcessLocked(ProcessRecord app,
2 String hostingType, String hostingNameStr) {
3 if (app.pid > 0 && app.pid != MY_PID) {
4 synchronized (mPidsSelfLocked) {
5 mPidsSelfLocked.remove(app.pid);
6 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
7 }
8 app.pid = 0;
9 }
10
11 mProcessesOnHold.remove(app);
12
13 updateCpuStats();
14
15 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
16 mProcDeaths[0] = 0;
17
18 try {
19 int uid = app.info.uid;
20 int[] gids = null;
21 try {
22 gids = mContext.getPackageManager().getPackageGids(
23 app.info.packageName);
24 } catch (PackageManager.NameNotFoundException e) {
25 Log.w(TAG, "Unable to retrieve gids", e);
26 }
27 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
28 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
29 && mTopComponent != null
30 && app.processName.equals(mTopComponent.getPackageName())) {
31 uid = 0;
32 }
33 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
34 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
35 uid = 0;
36 }
37 }
38 int debugFlags = 0;
39 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
40 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
41 }
42 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
43 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
44 }
45 if ("1".equals(SystemProperties.get("debug.assert"))) {
46 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
47 }
48 int pid = Process.start("android.app.ActivityThread",
49 mSimpleProcessManagement ? app.processName : null, uid, uid,
50 gids, debugFlags, null);
51 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
52 synchronized (bs) {
53 if (bs.isOnBattery()) {
54 app.batteryStats.incStartsLocked();
55 }
56 }
57
58 EventLog.writeEvent(LOG_AM_PROCESS_START, pid, uid,
59 app.processName, hostingType,
60 hostingNameStr != null ? hostingNameStr : "");
61
62 if (app.persistent) {
63 Watchdog.getInstance().processStarted(app, app.processName, pid);
64 }
65
66 StringBuilder buf = new StringBuilder(128);
67 buf.append("Start proc ");
68 buf.append(app.processName);
69 buf.append(" for ");
70 buf.append(hostingType);
71 if (hostingNameStr != null) {
72 buf.append(" ");
73 buf.append(hostingNameStr);
74 }
75 buf.append(": pid=");
76 buf.append(pid);
77 buf.append(" uid=");
78 buf.append(uid);
79 buf.append(" gids={");
80 if (gids != null) {
81 for (int gi=0; gi<gids.length; gi++) {
82 if (gi != 0) buf.append(", ");
83 buf.append(gids[gi]);
84
85 }
86 }
87 buf.append("}");
88 Log.i(TAG, buf.toString());
89 if (pid == 0 || pid == MY_PID) {
90 // Processes are being emulated with threads.
91 app.pid = MY_PID;
92 app.removed = false;
93 mStartingProcesses.add(app);
94 } else if (pid > 0) {
95 app.pid = pid;
96 app.removed = false;
97 synchronized (mPidsSelfLocked) {
98 this.mPidsSelfLocked.put(pid, app);
99 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
100 msg.obj = app;
101 mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT);
102 }
103 } else {
104 app.pid = 0;
105 RuntimeException e = new RuntimeException(
106 "Failure starting process " + app.processName
107 + ": returned pid=" + pid);
108 Log.e(TAG, e.getMessage(), e);
109 }
110 } catch (RuntimeException e) {
111 // XXX do better error recovery.
112 app.pid = 0;
113 Log.e(TAG, "Failure starting process " + app.processName, e);
114 }
115 }
這個(gè)進(jìn)程的主線程對(duì)應(yīng)有一個(gè)消息隊(duì)列(其他線程默認(rèn)是沒(méi)有消息隊(duì)列的,需要通過(guò)Looper.prepare();來(lái)創(chuàng)建,然后調(diào)用Looper.loop();來(lái)處理消息,參見(jiàn)Looper.java),這個(gè)Looper從Message Queue里面取message然后處理。
- 當(dāng)一個(gè)Activity finish的時(shí)候,這個(gè)activity實(shí)際并沒(méi)有銷(xiāo)毀,activity 的生命周期完全交給系統(tǒng)來(lái)管理 ,等系統(tǒng)在適當(dāng)?shù)臅r(shí)候來(lái)回收資源。只是簡(jiǎn)單的將位于堆棧里下一個(gè)activity彈出,將原來(lái)的activity壓棧而已,系統(tǒng)并保存原來(lái)的activity的一些歷史信息,并不銷(xiāo)毀,等下次打開(kāi)的時(shí)候,能夠很快的恢復(fù).
- 當(dāng)一個(gè)Activity finish的時(shí)候,它所在的進(jìn)程并沒(méi)有結(jié)束,所以這個(gè)應(yīng)用的主線程,包括主線程里面的message queue仍在運(yùn)行,進(jìn)程的退出是有Android系統(tǒng)來(lái)控制的,除非調(diào)用System.exit或者killProcess
- 當(dāng)再次運(yùn)行這個(gè)Activity的時(shí)候,還是在這個(gè)進(jìn)程的這個(gè)主線程里運(yùn)行。因此,在退出一個(gè)activity的時(shí)候,一定要注意將message queue的循環(huán)消息remove,將啟動(dòng)的工作線程,否則這些線程,消息隊(duì)列里的消息會(huì)成為孤魂野鬼,只有等待系統(tǒng)來(lái)回收了。
|