Handler与Android进程管理

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

你可能感兴趣的:(Handler与Android进程管理)