Calvin's Tech Space

成于坚忍,毁于浮躁

   :: 首页 :: 联系 :: 聚合  :: 管理
参考一篇文章:
http://blog.csdn.net/Android_Tutor/archive/2010/08/24/5834246.aspx

启示:
  1. 向Handler post一个Runnable对象的时候,并没有开启一个新的线程,只是将这个Runnable对象丢进message queue,处理的时候直接调用run()方法,参见Handler.java
    1     private final void handleCallback(Message message) {
    2         message.callback.run();
    3     }
  2. 一个应用在第一次运行的时候,确切的说在启动一个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然后处理。
  3. 当一个Activity finish的时候,这个activity实际并没有销毁,activity 的生命周期完全交给系统来管理 ,等系统在适当的时候来回收资源。只是简单的将位于堆栈里下一个activity弹出,将原来的activity压栈而已,系统并保存原来的activity的一些历史信息,并不销毁,等下次打开的时候,能够很快的恢复.
  4. 当一个Activity finish的时候,它所在的进程并没有结束,所以这个应用的主线程,包括主线程里面的message queue仍在运行,进程的退出是有Android系统来控制的,除非调用System.exit或者killProcess
  5. 当再次运行这个Activity的时候,还是在这个进程的这个主线程里运行。因此,在退出一个activity的时候,一定要注意将message queue的循环消息remove,将启动的工作线程,否则这些线程,消息队列里的消息会成为孤魂野鬼,只有等待系统来回收了。

posted on 2010-10-27 19:01 calvin 阅读(1039) 评论(0)  编辑  收藏 所属分类: Android

只有注册用户登录后才能发表评论。


网站导航: