Android应用程序启动过程源代码分析(2)

简介:
       Step 8. ActivityStack.startActivityLocked
        这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
 
 
  1. public  class ActivityStack {   
  2.    
  3.     ......   
  4.    
  5.      final  int startActivityLocked(IApplicationThread caller,   
  6.             Intent intent, String resolvedType,   
  7.             Uri[] grantedUriPermissions,   
  8.              int grantedMode, ActivityInfo aInfo, IBinder resultTo,   
  9.                 String resultWho,  int requestCode,   
  10.              int callingPid,  int callingUid,  boolean onlyIfNeeded,   
  11.              boolean componentSpecified) {   
  12.              int err = START_SUCCESS;   
  13.    
  14.         ProcessRecord callerApp =  null;   
  15.          if (caller !=  null) {   
  16.             callerApp = mService.getRecordForAppLocked(caller);   
  17.              if (callerApp !=  null) {   
  18.                 callingPid = callerApp.pid;   
  19.                 callingUid = callerApp.info.uid;   
  20.             }  else {   
  21.                 ......   
  22.             }   
  23.         }   
  24.    
  25.         ......   
  26.    
  27.         ActivityRecord sourceRecord =  null;   
  28.         ActivityRecord resultRecord =  null;   
  29.          if (resultTo !=  null) {   
  30.              int index = indexOfTokenLocked(resultTo);   
  31.                
  32.             ......   
  33.                    
  34.              if (index >=  0) {   
  35.                 sourceRecord = (ActivityRecord)mHistory.get(index);   
  36.                  if (requestCode >=  0 && !sourceRecord.finishing) {   
  37.                     ......   
  38.                 }   
  39.             }   
  40.         }   
  41.    
  42.          int launchFlags = intent.getFlags();   
  43.    
  44.          if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) !=  0   
  45.             && sourceRecord !=  null) {   
  46.             ......   
  47.         }   
  48.    
  49.          if (err == START_SUCCESS && intent.getComponent() ==  null) {   
  50.             ......   
  51.         }   
  52.    
  53.          if (err == START_SUCCESS && aInfo ==  null) {   
  54.             ......   
  55.         }   
  56.    
  57.          if (err != START_SUCCESS) {   
  58.             ......   
  59.         }   
  60.    
  61.         ......   
  62.    
  63.         ActivityRecord r =  new ActivityRecord(mService,  this, callerApp, callingUid,   
  64.             intent, resolvedType, aInfo, mService.mConfiguration,   
  65.             resultRecord, resultWho, requestCode, componentSpecified);   
  66.    
  67.         ......   
  68.    
  69.          return startActivityUncheckedLocked(r, sourceRecord,   
  70.             grantedUriPermissions, grantedMode, onlyIfNeeded,  true);   
  71.     }   
  72.    
  73.    
  74.     ......   
  75.    
  76. }   
        从传进来的参数caller得到调用者的进程信息,并保存在callerApp变量中,这里就是Launcher应用程序的进程信息了。
 
        前面说过,参数resultTo是Launcher这个Activity里面的一个Binder对象,通过它可以获得Launcher这个Activity的相关信息,保存在sourceRecord变量中。
        再接下来,创建即将要启动的Activity的相关信息,并保存在r变量中:
 
  
  1. ActivityRecord r =  new ActivityRecord(mService,  this, callerApp, callingUid,   
  2.     intent, resolvedType, aInfo, mService.mConfiguration,   
  3.     resultRecord, resultWho, requestCode, componentSpecified);   
        接着调用startActivityUncheckedLocked函数进行下一步操作。
 
        Step 9. ActivityStack.startActivityUncheckedLocked
        这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
 
 
  1. public  class ActivityStack {   
  2.    
  3.     ......   
  4.    
  5.      final  int startActivityUncheckedLocked(ActivityRecord r,   
  6.         ActivityRecord sourceRecord, Uri[] grantedUriPermissions,   
  7.          int grantedMode,  boolean onlyIfNeeded,  boolean doResume) {   
  8.          final Intent intent = r.intent;   
  9.          final  int callingUid = r.launchedFromUid;   
  10.    
  11.          int launchFlags = intent.getFlags();   
  12.    
  13.          // We'll invoke onUserLeaving before onPause only if the launching   
  14.          // activity did not explicitly state that this is an automated launch.   
  15.         mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) ==  0;   
  16.            
  17.         ......   
  18.    
  19.         ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)   
  20.             !=  0 ? r :  null;   
  21.    
  22.          // If the onlyIfNeeded flag is set, then we can do this if the activity   
  23.          // being launched is the same as the one making the call...  or, as   
  24.          // a special case, if we do not know the caller then we count the   
  25.          // current top activity as the caller.   
  26.          if (onlyIfNeeded) {   
  27.             ......   
  28.         }   
  29.    
  30.          if (sourceRecord ==  null) {   
  31.             ......   
  32.         }  else  if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {   
  33.             ......   
  34.         }  else  if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE   
  35.             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {   
  36.             ......   
  37.         }   
  38.    
  39.          if (r.resultTo !=  null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) !=  0) {   
  40.             ......   
  41.         }   
  42.    
  43.          boolean addingToTask =  false;   
  44.          if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) !=  0 &&   
  45.             (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) ==  0)   
  46.             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK   
  47.             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {   
  48.                  // If bring to front is requested, and no result is requested, and   
  49.                  // we can find a task that was started with this same   
  50.                  // component, then instead of launching bring that one to the front.   
  51.                  if (r.resultTo ==  null) {   
  52.                      // See if there is a task to bring to the front.  If this is   
  53.                      // a SINGLE_INSTANCE activity, there can be one and only one   
  54.                      // instance of it in the history, and it is always in its own   
  55.                      // unique task, so we do a special search.   
  56.                     ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE   
  57.                         ? findTaskLocked(intent, r.info)   
  58.                         : findActivityLocked(intent, r.info);   
  59.                      if (taskTop !=  null) {   
  60.                         ......   
  61.                     }   
  62.                 }   
  63.         }   
  64.    
  65.         ......   
  66.    
  67.          if (r.packageName !=  null) {   
  68.              // If the activity being launched is the same as the one currently   
  69.              // at the top, then we need to check if it should only be launched   
  70.              // once.   
  71.             ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);   
  72.              if (top !=  null && r.resultTo ==  null) {   
  73.                  if (top.realActivity.equals(r.realActivity)) {   
  74.                     ......   
  75.                 }   
  76.             }   
  77.    
  78.         }  else {   
  79.             ......   
  80.         }   
  81.    
  82.          boolean newTask =  false;   
  83.    
  84.          // Should this be considered a new task?   
  85.          if (r.resultTo ==  null && !addingToTask   
  86.             && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) !=  0) {   
  87.                  // todo: should do better management of integers.   
  88.                 mService.mCurTask++;   
  89.                  if (mService.mCurTask <=  0) {   
  90.                     mService.mCurTask =  1;   
  91.                 }   
  92.                 r.task =  new TaskRecord(mService.mCurTask, r.info, intent,   
  93.                     (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) !=  0);   
  94.                 ......   
  95.                 newTask =  true;   
  96.                  if (mMainStack) {   
  97.                     mService.addRecentTaskLocked(r.task);   
  98.                 }   
  99.    
  100.         }  else  if (sourceRecord !=  null) {   
  101.             ......   
  102.         }  else {   
  103.             ......   
  104.         }   
  105.    
  106.         ......   
  107.    
  108.         startActivityLocked(r, newTask, doResume);   
  109.          return START_SUCCESS;   
  110.     }   
  111.    
  112.     ......   
  113.    
  114. }   
        函数首先获得intent的标志值,保存在launchFlags变量中。
 
        这个intent的标志值的位Intent.FLAG_ACTIVITY_NO_USER_ACTION没有置位,因此 ,成员变量mUserLeaving的值为true。
        这个intent的标志值的位Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP也没有置位,因此,变量notTop的值为null。
        由于在这个例子的AndroidManifest.xml文件中,MainActivity没有配置launchMode属值,因此,这里的r.launchMode为默认值0,表示以标准(Standard,或者称为ActivityInfo.LAUNCH_MULTIPLE)的方式来启动这个Activity。Activity的启动方式有四种,其余三种分别是ActivityInfo.LAUNCH_SINGLE_INSTANCE、ActivityInfo.LAUNCH_SINGLE_TASK和ActivityInfo.LAUNCH_SINGLE_TOP,具体可以参考官方网站 http://developer.android.com/reference/android/content/pm/ActivityInfo.html
        传进来的参数r.resultTo为null,表示Launcher不需要等这个即将要启动的MainActivity的执行结果。
        由于这个intent的标志值的位Intent.FLAG_ACTIVITY_NEW_TASK被置位,而且Intent.FLAG_ACTIVITY_MULTIPLE_TASK没有置位,因此,下面的if语句会被执行:
 
 
  1.     if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) !=  0 &&   
  2. (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) ==  0)   
  3. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK   
  4. || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {   
  5.      // If bring to front is requested, and no result is requested, and   
  6.      // we can find a task that was started with this same   
  7.      // component, then instead of launching bring that one to the front.   
  8.      if (r.resultTo ==  null) {   
  9.          // See if there is a task to bring to the front.  If this is   
  10.          // a SINGLE_INSTANCE activity, there can be one and only one   
  11.          // instance of it in the history, and it is always in its own   
  12.          // unique task, so we do a special search.   
  13.         ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE   
  14.             ? findTaskLocked(intent, r.info)   
  15.             : findActivityLocked(intent, r.info);   
  16.          if (taskTop !=  null) {   
  17.             ......   
  18.         }   
  19.     }   
  20.    }   
 
        这段代码的逻辑是查看一下,当前有没有Task可以用来执行这个Activity。由于r.launchMode的值不为ActivityInfo.LAUNCH_SINGLE_INSTANCE,因此,它通过findTaskLocked函数来查找存不存这样的Task,这里返回的结果是null,即taskTop为null,因此,需要创建一个新的Task来启动这个Activity。
 
        接着往下看:
 
 
  1.     if (r.packageName !=  null) {   
  2. // If the activity being launched is the same as the one currently   
  3. // at the top, then we need to check if it should only be launched   
  4. // once.   
  5. ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);   
  6. if (top !=  null && r.resultTo ==  null) {   
  7.      if (top.realActivity.equals(r.realActivity)) {   
  8.         ......   
  9.     }   
  10. }   
  11.    
  12.    }    
 
        这段代码的逻辑是看一下,当前在堆栈顶端的Activity是否就是即将要启动的Activity,有些情况下,如果即将要启动的Activity就在堆栈的顶端,那么,就不会重新启动这个Activity的别一个实例了,具体可以参考官方网站 http://developer.android.com/reference/android/content/pm/ActivityInfo.html 。现在处理堆栈顶端的Activity是Launcher,与我们即将要启动的MainActivity不是同一个Activity,因此,这里不用进一步处理上述介绍的情况。
 
       执行到这里,我们知道,要在一个新的Task里面来启动这个Activity了,于是新创建一个Task:
 
 
  1.    if (r.resultTo ==  null && !addingToTask   
  2. && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) !=  0) {   
  3. // todo: should do better management of integers.   
  4. mService.mCurTask++;   
  5. if (mService.mCurTask <=  0) {   
  6.     mService.mCurTask =  1;   
  7. }   
  8. r.task =  new TaskRecord(mService.mCurTask, r.info, intent,   
  9.     (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) !=  0);   
  10. ......   
  11. newTask =  true;   
  12. if (mMainStack) {   
  13.     mService.addRecentTaskLocked(r.task);   
  14. }   
  15.    
  16.    }   
 
       新建的Task保存在r.task域中,同时,添加到mService中去,这里的mService就是ActivityManagerService了。
 
        最后就进入startActivityLocked(r, newTask, doResume)进一步处理了。这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
 
 
  1. public  class ActivityStack {   
  2.    
  3.     ......   
  4.    
  5.      private  final  void startActivityLocked(ActivityRecord r,  boolean newTask,   
  6.              boolean doResume) {   
  7.          final  int NH = mHistory.size();   
  8.    
  9.          int addPos = - 1;   
  10.    
  11.          if (!newTask) {   
  12.             ......   
  13.         }   
  14.    
  15.          // Place a new activity at top of stack, so it is next to interact   
  16.          // with the user.   
  17.          if (addPos <  0) {   
  18.             addPos = NH;   
  19.         }   
  20.    
  21.          // If we are not placing the new activity frontmost, we do not want   
  22.          // to deliver the onUserLeaving callback to the actual frontmost   
  23.          // activity   
  24.          if (addPos < NH) {   
  25.             ......   
  26.         }   
  27.    
  28.          // Slot the activity into the history stack and proceed   
  29.         mHistory.add(addPos, r);   
  30.         r.inHistory =  true;   
  31.         r.frontOfTask = newTask;   
  32.         r.task.numActivities++;   
  33.          if (NH >  0) {   
  34.              // We want to show the starting preview window if we are   
  35.              // switching to a new task, or the next activity's process is   
  36.              // not currently running.   
  37.             ......   
  38.         }  else {   
  39.              // If this is the first activity, don't do any fancy animations,   
  40.              // because there is nothing for it to animate on top of.   
  41.             ......   
  42.         }   
  43.            
  44.         ......   
  45.    
  46.          if (doResume) {   
  47.             resumeTopActivityLocked( null);   
  48.         }   
  49.     }   
  50.    
  51.     ......   
  52.    
  53. }   
 
        这里的NH表示当前系统中历史任务的个数,这里肯定是大于0,因为Launcher已经跑起来了。当NH>0时,并且现在要切换新任务时,要做一些任务切的界面操作,这段代码我们就不看了,这里不会影响到下面启Activity的过程,有兴趣的读取可以自己研究一下。
 
        这里传进来的参数doResume为true,于是调用resumeTopActivityLocked进一步操作。
        Step 10. Activity.resumeTopActivityLocked
        这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
 
 
  1. public  class ActivityStack {   
  2.    
  3.     ......   
  4.    
  5.      /**  
  6.     * Ensure that the top activity in the stack is resumed.  
  7.     *  
  8.     * @param prev The previously resumed activity, for when in the process  
  9.     * of pausing; can be null to call from elsewhere.  
  10.     *  
  11.     * @return Returns true if something is being resumed, or false if  
  12.     * nothing happened.  
  13.     */   
  14.      final  boolean resumeTopActivityLocked(ActivityRecord prev) {   
  15.          // Find the first activity that is not finishing.   
  16.         ActivityRecord next = topRunningActivityLocked( null);   
  17.    
  18.          // Remember how we'll process this pause/resume situation, and ensure   
  19.          // that the state is reset however we wind up proceeding.   
  20.          final  boolean userLeaving = mUserLeaving;   
  21.         mUserLeaving =  false;   
  22.    
  23.          if (next ==  null) {   
  24.             ......   
  25.         }   
  26.    
  27.         next.delayedResume =  false;   
  28.    
  29.          // If the top activity is the resumed one, nothing to do.   
  30.          if (mResumedActivity == next && next.state == ActivityState.RESUMED) {   
  31.             ......   
  32.         }   
  33.    
  34.          // If we are sleeping, and there is no resumed activity, and the top   
  35.          // activity is paused, well that is the state we want.   
  36.          if ((mService.mSleeping || mService.mShuttingDown)   
  37.             && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {   
  38.             ......   
  39.         }   
  40.    
  41.         ......   
  42.    
  43.          // If we are currently pausing an activity, then don't do anything   
  44.          // until that is done.   
  45.          if (mPausingActivity !=  null) {   
  46.             ......   
  47.         }   
  48.    
  49.         ......   
  50.    
  51.          // We need to start pausing the current activity so the top one   
  52.          // can be resumed...   
  53.          if (mResumedActivity !=  null) {   
  54.             ......   
  55.             startPausingLocked(userLeaving,  false);   
  56.              return  true;   
  57.         }   
  58.    
  59.         ......   
  60.     }   
  61.    
  62.     ......   
  63.    
  64. }   
 
        函数先通过调用topRunningActivityLocked函数获得堆栈顶端的Activity,这里就是MainActivity了,这是在上面的Step 9设置好的,保存在next变量中。 
 
       接下来把mUserLeaving的保存在本地变量userLeaving中,然后重新设置为false,在上面的Step 9中,mUserLeaving的值为true,因此,这里的userLeaving为true。
       这里的mResumedActivity为Launcher,因为Launcher是当前正被执行的Activity。
       当我们处理休眠状态时,mLastPausedActivity保存堆栈顶端的Activity,因为当前不是休眠状态,所以mLastPausedActivity为null。
       有了这些信息之后,下面的语句就容易理解了:
 
 
  1.     // If the top activity is the resumed one, nothing to do.   
  2.     if (mResumedActivity == next && next.state == ActivityState.RESUMED) {   
  3. ......   
  4.    }   
  5.    
  6.     // If we are sleeping, and there is no resumed activity, and the top   
  7.     // activity is paused, well that is the state we want.   
  8.     if ((mService.mSleeping || mService.mShuttingDown)   
  9. && mLastPausedActivity == next && next.state == ActivityState.PAUSED) {   
  10. ......   
  11.    }   
 
        它首先看要启动的Activity是否就是当前处理Resumed状态的Activity,如果是的话,那就什么都不用做,直接返回就可以了;否则再看一下系统当前是否休眠状态,如果是的话,再看看要启动的Activity是否就是当前处于堆栈顶端的Activity,如果是的话,也是什么都不用做。
 
        上面两个条件都不满足,因此,在继续往下执行之前,首先要把当处于Resumed状态的Activity推入Paused状态,然后才可以启动新的Activity。但是在将当前这个Resumed状态的Activity推入Paused状态之前,首先要看一下当前是否有Activity正在进入Pausing状态,如果有的话,当前这个Resumed状态的Activity就要稍后才能进入Paused状态了,这样就保证了所有需要进入Paused状态的Activity串行处理。
        这里没有处于Pausing状态的Activity,即mPausingActivity为null,而且mResumedActivity也不为null,于是就调用startPausingLocked函数把Launcher推入Paused状态去了。
        Step 11. ActivityStack.startPausingLocked
        这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
 
 
  1. public  class ActivityStack {   
  2.    
  3.     ......   
  4.    
  5.      private  final  void startPausingLocked( boolean userLeaving,  boolean uiSleeping) {   
  6.          if (mPausingActivity !=  null) {   
  7.             ......   
  8.         }   
  9.         ActivityRecord prev = mResumedActivity;   
  10.          if (prev ==  null) {   
  11.             ......   
  12.         }   
  13.         ......   
  14.         mResumedActivity =  null;   
  15.         mPausingActivity = prev;   
  16.         mLastPausedActivity = prev;   
  17.         prev.state = ActivityState.PAUSING;   
  18.         ......   
  19.    
  20.          if (prev.app !=  null && prev.app.thread !=  null) {   
  21.             ......   
  22.              try {   
  23.                 ......   
  24.                 prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving,   
  25.                     prev.configChangeFlags);   
  26.                 ......   
  27.             }  catch (Exception e) {   
  28.                 ......   
  29.             }   
  30.         }  else {   
  31.             ......   
  32.         }   
  33.    
  34.         ......   
  35.        
  36.     }   
  37.    
  38.     ......   
  39.    
  40. }   
 
 
        函数首先把mResumedActivity保存在本地变量prev中。在上一步Step 10中,说到mResumedActivity就是Launcher,因此,这里把Launcher进程中的ApplicationThread对象取出来,通过它来通知Launcher这个Activity它要进入Paused状态了。当然,这里的prev.app.thread是一个ApplicationThread对象的远程接口,通过调用这个远程接口的schedulePauseActivity来通知Launcher进入Paused状态。
       参数prev.finishing表示prev所代表的Activity是否正在等待结束的Activity列表中,由于Laucher这个Activity还没结束,所以这里为false;参数prev.configChangeFlags表示哪些config发生了变化,这里我们不关心它的值。
       Step 12. ApplicationThreadProxy.schedulePauseActivity
       这个函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:
 
 
  1. class ApplicationThreadProxy  implements IApplicationThread {   
  2.        
  3.     ......   
  4.    
  5.      public  final  void schedulePauseActivity(IBinder token,  boolean finished,   
  6.      boolean userLeaving,  int configChanges)  throws RemoteException {   
  7.         Parcel data = Parcel.obtain();   
  8.         data.writeInterfaceToken(IApplicationThread.descriptor);   
  9.         data.writeStrongBinder(token);   
  10.         data.writeInt(finished ?  1 :  0);   
  11.         data.writeInt(userLeaving ?  1 : 0);   
  12.         data.writeInt(configChanges);   
  13.         mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data,  null,   
  14.             IBinder.FLAG_ONEWAY);   
  15.         data.recycle();   
  16.     }   
  17.    
  18.     ......   
  19.    
  20. }   
 
 
        这个函数通过Binder进程间通信机制进入到ApplicationThread.schedulePauseActivity函数中。
        Step 13. ApplicationThread.schedulePauseActivity
        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中,它是ActivityThread的内部类:
 
 
  1. public  final  class ActivityThread {   
  2.        
  3.     ......   
  4.    
  5.      private  final  class ApplicationThread  extends ApplicationThreadNative {   
  6.            
  7.         ......   
  8.    
  9.          public  final  void schedulePauseActivity(IBinder token,  boolean finished,   
  10.                  boolean userLeaving,  int configChanges) {   
  11.             queueOrSendMessage(   
  12.                 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,   
  13.                 token,   
  14.                 (userLeaving ?  1 :  0),   
  15.                 configChanges);   
  16.         }   
  17.    
  18.         ......   
  19.    
  20.     }   
  21.    
  22.     ......   
  23.    
  24. }   
 
        这里调用的函数queueOrSendMessage是ActivityThread类的成员函数。
 
       上面说到,这里的finished值为false,因此,queueOrSendMessage的第一个参数值为H.PAUSE_ACTIVITY,表示要暂停token所代表的Activity,即Launcher。
       Step 14. ActivityThread.queueOrSendMessage
       这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
 
 
  1. public  final  class ActivityThread {   
  2.        
  3.     ......   
  4.    
  5.      private  final  void queueOrSendMessage( int what, Object obj,  int arg1) {   
  6.         queueOrSendMessage(what, obj, arg1,  0);   
  7.     }   
  8.    
  9.      private  final  void queueOrSendMessage( int what, Object obj,  int arg1,  int arg2) {   
  10.          synchronized ( this) {   
  11.             ......   
  12.             Message msg = Message.obtain();   
  13.             msg.what = what;   
  14.             msg.obj = obj;   
  15.             msg.arg1 = arg1;   
  16.             msg.arg2 = arg2;   
  17.             mH.sendMessage(msg);   
  18.         }   
  19.     }   
  20.    
  21.     ......   
  22.    
  23. }   
 
        这里首先将相关信息组装成一个msg,然后通过mH成员变量发送出去,mH的类型是H,继承于Handler类,是ActivityThread的内部类,因此,这个消息最后由H.handleMessage来处理。
 
        Step 15. H.handleMessage
        这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
 
 
  1. public  final  class ActivityThread {   
  2.        
  3.     ......   
  4.    
  5.      private  final  class H  extends Handler {   
  6.    
  7.         ......   
  8.    
  9.          public  void handleMessage(Message msg) {   
  10.             ......   
  11.              switch (msg.what) {   
  12.                
  13.             ......   
  14.                
  15.              case PAUSE_ACTIVITY:   
  16.                 handlePauseActivity((IBinder)msg.obj,  false, msg.arg1 !=  0, msg.arg2);   
  17.                 maybeSnapshot();   
  18.                  break;   
  19.    
  20.             ......   
  21.    
  22.             }   
  23.         ......   
  24.    
  25.     }   
  26.    
  27.     ......   
  28.    
  29. }   
 
        这里调用ActivityThread.handlePauseActivity进一步操作,msg.obj是一个ActivityRecord对象的引用,它代表的是Launcher这个Activity。         
 




本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/965996,如需转载请自行联系原作者

目录
相关文章
|
14天前
|
安全 Android开发 数据安全/隐私保护
深入探讨iOS与Android系统安全性对比分析
在移动操作系统领域,iOS和Android无疑是两大巨头。本文从技术角度出发,对这两个系统的架构、安全机制以及用户隐私保护等方面进行了详细的比较分析。通过深入探讨,我们旨在揭示两个系统在安全性方面的差异,并为用户提供一些实用的安全建议。
|
23天前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
46 15
Android 系统缓存扫描与清理方法分析
|
14天前
|
JSON Java Android开发
探索安卓开发之旅:打造你的第一个天气应用
【10月更文挑战第30天】在这个数字时代,掌握移动应用开发技能无疑是进入IT行业的敲门砖。本文将引导你开启安卓开发的奇妙之旅,通过构建一个简易的天气应用来实践你的编程技能。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你宝贵的学习资源。我们将一步步地深入到安卓开发的世界中,从搭建开发环境到实现核心功能,每个环节都充满了发现和创造的乐趣。让我们开始吧,一起在代码的海洋中航行!
|
14天前
|
存储 搜索推荐 Java
打造个性化安卓应用:从设计到实现
【10月更文挑战第30天】在数字化时代,拥有一个个性化的安卓应用不仅能够提升用户体验,还能加强品牌识别度。本文将引导您了解如何从零开始设计和实现一个安卓应用,涵盖用户界面设计、功能开发和性能优化等关键环节。我们将以一个简单的记事本应用为例,展示如何通过Android Studio工具和Java语言实现基本功能,同时确保应用流畅运行。无论您是初学者还是希望提升现有技能的开发者,这篇文章都将为您提供宝贵的见解和实用的技巧。
|
18天前
|
搜索推荐 开发工具 Android开发
打造个性化Android应用:从设计到实现的旅程
【10月更文挑战第26天】在这个数字时代,拥有一个能够脱颖而出的移动应用是成功的关键。本文将引导您了解如何从概念化阶段出发,通过设计、开发直至发布,一步步构建一个既美观又实用的Android应用。我们将探讨用户体验(UX)设计的重要性,介绍Android开发的核心组件,并通过实际案例展示如何克服开发中的挑战。无论您是初学者还是有经验的开发者,这篇文章都将为您提供宝贵的见解和实用的技巧,帮助您在竞争激烈的应用市场中脱颖而出。
|
20天前
|
算法 Java 数据库
Android 应用的主线程在什么情况下会被阻塞?
【10月更文挑战第20天】为了避免主线程阻塞,我们需要合理地设计和优化应用的代码。将耗时操作移到后台线程执行,使用异步任务、线程池等技术来提高应用的并发处理能力。同时,要注意避免出现死循环、不合理的锁使用等问题。通过这些措施,可以确保主线程能够高效地运行,提供流畅的用户体验。
31 2
|
24天前
|
Java API Android开发
安卓应用程序开发的新手指南:从零开始构建你的第一个应用
【10月更文挑战第20天】在这个数字技术不断进步的时代,掌握移动应用开发技能无疑打开了一扇通往创新世界的大门。对于初学者来说,了解并学习如何从无到有构建一个安卓应用是至关重要的第一步。本文将为你提供一份详尽的入门指南,帮助你理解安卓开发的基础知识,并通过实际示例引导你完成第一个简单的应用项目。无论你是编程新手还是希望扩展你的技能集,这份指南都将是你宝贵的资源。
48 5
|
24天前
|
移动开发 Dart 搜索推荐
打造个性化安卓应用:从零开始的Flutter之旅
【10月更文挑战第20天】本文将引导你开启Flutter开发之旅,通过简单易懂的语言和步骤,让你了解如何从零开始构建一个安卓应用。我们将一起探索Flutter的魅力,实现快速开发,并见证代码示例如何生动地转化为用户界面。无论你是编程新手还是希望扩展技能的开发者,这篇文章都将为你提供价值。
|
1月前
|
调度 Android开发 开发者
构建高效Android应用:探究Kotlin多线程优化策略
【10月更文挑战第11天】本文探讨了如何在Kotlin中实现高效的多线程方案,特别是在Android应用开发中。通过介绍Kotlin协程的基础知识、异步数据加载的实际案例,以及合理使用不同调度器的方法,帮助开发者提升应用性能和用户体验。
46 4
|
Android开发
Android--退出整个应用程序
版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/chaoyu168/article/details/52229304 在写android应用程序时,经常会遇到想退出当前Acitivity,或者直接退出应用程序.我之前的一般操作是按返回键,或者直接按home键直接返回,其实这两种操作都没有关闭当前应用程序,没有释放系统资源。
894 0