Calvin's Tech Space

          成于堅(jiān)忍,毀于浮躁

             :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
          參考一篇文章:
          http://blog.csdn.net/Android_Tutor/archive/2010/08/24/5834246.aspx

          啟示:
          1. 向Handler post一個(gè)Runnable對(duì)象的時(shí)候,并沒有開啟一個(gè)新的線程,只是將這個(gè)Runnable對(duì)象丟進(jìn)message queue,處理的時(shí)候直接調(diào)用run()方法,參見Handler.java
            1     private final void handleCallback(Message message) {
            2         message.callback.run();
            3     }
          2. 一個(gè)應(yīng)用在第一次運(yùn)行的時(shí)候,確切的說在啟動(dòng)一個(gè)activity的時(shí)候,Dalvik會(huì)為這個(gè)應(yīng)用創(chuàng)建一個(gè)進(jì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)是沒有消息隊(duì)列的,需要通過Looper.prepare();來創(chuàng)建,然后調(diào)用Looper.loop();來處理消息,參見Looper.java),這個(gè)Looper從Message Queue里面取message然后處理。
          3. 當(dāng)一個(gè)Activity finish的時(shí)候,這個(gè)activity實(shí)際并沒有銷毀,activity 的生命周期完全交給系統(tǒng)來管理 ,等系統(tǒng)在適當(dāng)?shù)臅r(shí)候來回收資源。只是簡(jiǎn)單的將位于堆棧里下一個(gè)activity彈出,將原來的activity壓棧而已,系統(tǒng)并保存原來的activity的一些歷史信息,并不銷毀,等下次打開的時(shí)候,能夠很快的恢復(fù).
          4. 當(dāng)一個(gè)Activity finish的時(shí)候,它所在的進(jìn)程并沒有結(jié)束,所以這個(gè)應(yīng)用的主線程,包括主線程里面的message queue仍在運(yùn)行,進(jìn)程的退出是有Android系統(tǒng)來控制的,除非調(diào)用System.exit或者killProcess
          5. 當(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)來回收了。

          posted on 2010-10-27 19:01 calvin 閱讀(1049) 評(píng)論(0)  編輯  收藏 所屬分類: Android
          主站蜘蛛池模板: 将乐县| 桑日县| 喀喇沁旗| 白山市| 平顶山市| 萨嘎县| 鸡西市| 巴林左旗| 奉化市| 焉耆| 调兵山市| 瓦房店市| 霸州市| 蓝田县| 蓝山县| 玉山县| 康乐县| 铅山县| 花莲市| 磐安县| 会宁县| 苏尼特右旗| 三门峡市| 天峻县| 普陀区| 安徽省| 金堂县| 太白县| 游戏| 顺平县| 宜昌市| 揭东县| 元谋县| 赤水市| 苍梧县| 铜鼓县| 绍兴县| 寻甸| 开远市| 广饶县| 仪征市|