参考一篇文章:
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,将启动的工作线程,否则这些线程,消息队列里的消息会成为孤魂野鬼,只有等待系统来回收了。
|