參考一篇文章:
http://blog.csdn.net/Android_Tutor/archive/2010/08/24/5834246.aspx
啟示:
- 向Handler post一個Runnable對象的時候,并沒有開啟一個新的線程,只是將這個Runnable對象丟進message queue,處理的時候直接調用run()方法,參見Handler.java
1 private final void handleCallback(Message message) {
2 message.callback.run();
3 }
- 一個應用在第一次運行的時候,確切的說在啟動一個activity的時候,Dalvik會為這個應用創建一個進程。參見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 }
這個進程的主線程對應有一個消息隊列(其他線程默認是沒有消息隊列的,需要通過Looper.prepare();來創建,然后調用Looper.loop();來處理消息,參見Looper.java),這個Looper從Message Queue里面取message然后處理。
- 當一個Activity finish的時候,這個activity實際并沒有銷毀,activity 的生命周期完全交給系統來管理 ,等系統在適當的時候來回收資源。只是簡單的將位于堆棧里下一個activity彈出,將原來的activity壓棧而已,系統并保存原來的activity的一些歷史信息,并不銷毀,等下次打開的時候,能夠很快的恢復.
- 當一個Activity finish的時候,它所在的進程并沒有結束,所以這個應用的主線程,包括主線程里面的message queue仍在運行,進程的退出是有Android系統來控制的,除非調用System.exit或者killProcess
- 當再次運行這個Activity的時候,還是在這個進程的這個主線程里運行。因此,在退出一個activity的時候,一定要注意將message queue的循環消息remove,將啟動的工作線程,否則這些線程,消息隊列里的消息會成為孤魂野鬼,只有等待系統來回收了。
|