返回介绍

Android Activity.startActivity 流程简介

发布于 2025-02-28 12:35:46 字数 18706 浏览 0 评论 0 收藏 0

1. 基本概念

1.1 Instrumentation 是什么?

顾名思义,仪器仪表,用于在应用程序中进行“测量”和“管理”工作。一个应用程序中只有一个 Instrumentation 实例对象,且每个 Activity 都有此对象的引用。Instrumentation 将在任何应用程序运行前初始化,可以通过它监测系统与应用程序之间的所有交互,即类似于在系统与应用程序之间安装了个“窃听器”。

当 ActivityThread 创建(callActivityOnCreate)、暂停、恢复某个 Activity 时,通过调用此对象的方法来实现,如:

1) 创建: callActivityOnCreate

2) 暂停: callActivityOnPause

3) 恢复: callActivityOnResume

Instrumentation 和 ActivityThread 的关系,类似于老板与经理的关系,老板负责对外交流(如与 Activity Manager Service),Instrumentation 负责管理并完成老板交待的任务。

它通过以下两个成员变量来对当前应用进程中的 Activity 进行管理:

 private List<ActivityWaiter> mWaitingActivities;  
 private List<ActivityMonitor> mActivityMonitors;  

其功能函数下表所示:

功能函数
增加删除 MonitoraddMonitor(ActivityMonitor monitor)
removeMonitor(ActivityMonitor monitor)
Application 与 Activity 生命周期控制newApplication(Class<?> clazz, Context context)
newActivity(ClassLoader cl, String className,Intent intent)
callActivityOnCreate(Activity activity, Bundle icicle)
callActivityOnDestroy(Activity activity)
callActivityOnStart(Activity activity)
callActivityOnRestart(Activity activity)
callActivityOnResume(Activity activity)
callActivityOnStop(Activity activity)
callActivityOnPause(Activity activity)
Instrumentation 生命周期控制onCreate(Bundle arguments)
start()
onStart()
finish(int resultCode, Bundle results)
onDestroy()
发送用户操控信息到当前窗口sendCharacterSync(int keyCode)
sendPointerSync(MotionEvent event)
sendTrackballEventSync(MotionEvent event)
sendTrackballEventSync(MotionEvent event)
同步操作startActivitySync(Intent intent) //它调用 Context.startActivity
runOnMainSync(Runnable runner)
waitForIdle()

2. Android 应用程序启动过程(MainActivity)

即 MainActivity 的启动过程,在此过程中,将创建一个新的进程来执行此 MainActivity。

Android 应用程序从 Launcher 启动流程如下所示:

 /***************************************************************** 
  * Launcher 通过 Binder 告诉 ActivityManagerService, 
  * 它将要启动一个新的 Activity; 
  ****************************************************************/  
 Launcher.startActivitySafely->  
 Launcher.startActivity->  
  //要求在新的 Task 中启动此 Activity  
  //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)  
  Activity.startActivity->  
  Activity.startActivityForResult->  
  Instrumentation.execStartActivity->  
   // ActivityManagerNative.getDefault() 返回 AMS Proxy 接口  
   ActivityManagerNative.getDefault().startActivity->  
   ActivityManagerProxy.startActivity->  
   
  ActivityManagerService.startActivity-> (AMS)  
  ActivityManagerService.startActivityAsUser->   
   
   ActivityStack.startActivityMayWait->  
   ActivityStack.resolveActivity(获取 ActivityInfo)  
     //aInfo.name 为 main Activity,如:com.my.test.MainActivity  
     //aInfo.applicationInfo.packageName 为包名,如 com.my.test  
   ActivityStack.startActivityLocked->  
     //ProcessRecord callerApp; 调用者即 Launcher 信息  
     //ActivityRecord sourceRecord; Launcher Activity 相关信息  
     //ActivityRecord r=new ActivityRecord(...),将要创建的 Activity 相关信息    
   ActivityStack.startActivityUncheckedLocked->  
    //Activity 启动方式:ActivityInfo.LAUNCH_MULTIPLE/LAUNCH_SINGLE_INSTANCE/  
    //       ActivityInfo.LAUNCH_SINGLE_TASK/LAUNCH_SINGLE_TOP)  
    // 创建一个新的 task,即 TaskRecord,并保存在 ActivityRecord.task 中  
    //r.setTask(new TaskRecord(mService.mCurTask, r.info, intent), null, true)  
    // 把新创建的 Activity 放在栈顶     
    ActivityStack.startActivityLocked->  
    ActivityStack.resumeTopActivityLocked->  
    ActivityStack.startPausingLocked (使 Launcher 进入 Paused 状态)->    
   
    /***************************************************************** 
     * AMS 通过 Binder 通知 Launcher 进入 Paused 状态 
     ****************************************************************/  
     ApplicationThreadProxy.schedulePauseActivity->   
     //private class ApplicationThread extends ApplicationThreadNative  
     ApplicationThread.schedulePauseActivity->  
   
    ActivityThread.queueOrSendMessage->  
    
    // 调用 Activity.onUserLeaveHint  
    // 调用 Activity.onPause  
    // 通知 activity manager 我进入了 pause 状态  
    ActivityThread.handlePauseActivity->  
   
    /***************************************************************** 
     * Launcher 通过 Binder 告诉 AMS,它已经进入 Paused 状态 
     ****************************************************************/  
    ActivityManagerProxy.activityPaused->  
    ActivityManagerService.activityPaused->  
    ActivityStack.activityPaused->(把 Activity 状态修改为 PAUSED)  
    ActivityStack.completePauseLocked->  
     
    // 参数为代表 Launcher 这个 Activity 的 ActivityRecord  
    // 使用栈顶的 Activity 进入 RESUME 状态  
    ActivityStack.resumeTopActivityLokced->  
      //topRunningActivityLocked 将刚创建的放于栈顶的 activity 取回来  
      // 即在 ActivityStack.startActivityUncheckedLocked 中创建的  
   
    /***************************************************************** 
     * AMS 创建一个新的进程,用来启动一个 ActivityThread 实例, 
     * 即将要启动的 Activity 就是在这个 ActivityThread 实例中运行 
     ****************************************************************/  
    ActivityStack.startSpecificActivityLocked->  
   
     // 创建对应的 ProcessRecord  
     ActivityManagerService.startProcessLocked->  
       
      // 启动一个新的进程  
      // 新的进程会导入 android.app.ActivityThread 类,并且执行它的 main 函数,  
      // 即实例化 ActivityThread, 每个应用有且仅有一个 ActivityThread 实例  
      Process.start("android.app.ActivityThread",...)->  
   
      // 通过 zygote 机制创建一个新的进程  
      Process.startViaZygote->  
     
      // 这个函数在进程中创建一个 ActivityThread 实例,然后调用  
      // 它的 attach 函数,接着就进入消息循环  
      ActivityThread.main->  
   
      /***************************************************************** 
       * ActivityThread 通过 Binder 将一个 ApplicationThread 类的 Binder 对象 
       * 传递给 AMS,以便 AMS 通过此 Binder 对象来控制 Activity 整个生命周期 
       ****************************************************************/  
      ActivityThread.attach->  
      IActivityManager.attachApplication(mAppThread)->  
      ActivityManagerProxy.attachApplication->  
      ActivityManagerService.attachApplication->  
   
      // 把在 ActivityManagerService.startProcessLocked 中创建的 ProcessRecord 取出来  
      ActivityManagerService.attachApplicationLocked->  
   
      /***************************************************************** 
       * AMS 通过 Binder 通知 ActivityThread 一切准备 OK,它可以真正启动新的 Activity 了 
       ****************************************************************/        
      // 真正启动 Activity  
      ActivityStack.realStartActivityLocked->  
      ApplicationThreadProxy.scheduleLaunchActivity->  
      ApplicationThread.scheduleLaunchActivity->  
      ActivityThread.handleLaunchActivity->  
      // 加载新的 Activity 类,并执行它的 onCreate  
      ActivityThread.performLaunchActivity  
       /*1) Instrumentation.newActivity: 加载新类,即创建 Activity 对象;  
         2) ActivityClientRecord.packageInfo.makeApplication:创建 Application 对象;  
          <LoadedApk.makeApplication>  
         3) Activity.attach(Context context, ActivityThread aThread,  
           Instrumentation instr, IBinder token, int ident,  
           Application application, Intent intent, ActivityInfo info,  
           CharSequence title, Activity parent, String id,  
           NonConfigurationInstances lastNonConfigurationInstances,  
           Configuration config):把 Application attach 到 Activity, 即把 Activtiy  
                      相关信息设置到新创建的 Activity 中  
         4) Instrumentation.callActivityOnCreate:调用 onCreate;*/  
     
      // 使用 Activity 进入 RESUMED 状态,并调用 onResume  
      ActivityThread.handleResumeActivity  

3. ActivityManagerService

3.1 类中关键信息

 public final class ActivityManagerService extends ActivityManagerNative  
     implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {  
   ...  
   // Maximum number of recent tasks that we can remember.  
   static final int MAX_RECENT_TASKS = 20;  
   
   public ActivityStack mMainStack; // 管理 Activity 堆栈  
   
   // Whether we should show our dialogs (ANR, crash, etc) or just perform their  
   // default actuion automatically.  Important for devices without direct input  
   // devices.  
   private boolean mShowDialogs = true;  
   
   /** 
    * Description of a request to start a new activity, which has been held 
    * due to app switches being disabled. 
    */  
   static class PendingActivityLaunch {  
     ActivityRecord r;  
     ActivityRecord sourceRecord;  
     int startFlags;  
   }  
   
   
   /** 
    * Activity we have told the window manager to have key focus. 
    */  
   ActivityRecord mFocusedActivity = null;  
   
   /** 
    * List of intents that were used to start the most recent tasks. 
    */  
   final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();  
   
   /** 
    * Process management. 
    */  
   final ProcessList mProcessList = new ProcessList();  
   
   /** 
    * All of the applications we currently have running organized by name. 
    * The keys are strings of the application package name (as 
    * returned by the package manager), and the keys are ApplicationRecord 
    * objects. 
    */  
   final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();  
   
   /** 
    * The currently running isolated processes. 
    */  
   final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();  
   ...  
   
   public static final Context main(int factoryTest) { //main 入口函数  
     AThread thr = new AThread();  
     thr.start();  
   
     synchronized (thr) {  
       while (thr.mService == null) {  
         try {  
           thr.wait();  
         } catch (InterruptedException e) {  
         }  
       }  
     }  
   
     ActivityManagerService m = thr.mService;  
     mSelf = m;  
     ActivityThread at = ActivityThread.systemMain();  
     mSystemThread = at;  
     Context context = at.getSystemContext();  
     context.setTheme(android.R.style.Theme_Holo);  
     m.mContext = context;  
     m.mFactoryTest = factoryTest;  
     m.mMainStack = new ActivityStack(m, context, true); // 创建 ActivityStack  
       
     m.mBatteryStatsService.publish(context);  
     m.mUsageStatsService.publish(context);  
       
     synchronized (thr) {  
       thr.mReady = true;  
       thr.notifyAll();  
     }  
   
     m.startRunning(null, null, null, null);  
       
     return context;  
   }  
 }  

3.2 家族图谱

4. ActivityStack-真正做事的家伙

ActivityManagerService 使用它来管理系统中所有的 Activities 的状态,Activities 使用 stack 的方式进行管理。它是真正负责做事的家伙,很勤快的,但外界无人知道!

4.1 类中关键信息

 /** 
  * State and management of a single stack of activities. 
  */  
 final class ActivityStack {  
   final ActivityManagerService mService;  
   final boolean mMainStack;  
   final Context mContext;  
   
   enum ActivityState {  
     INITIALIZING,  
     RESUMED,  
     PAUSING,  
     PAUSED,  
     STOPPING,  
     STOPPED,  
     FINISHING,  
     DESTROYING,  
     DESTROYED  
   }  
   
   /** 
    * The back history of all previous (and possibly still 
    * running) activities.  It contains HistoryRecord objects. 
    */  
   final ArrayList<ActivityRecord> mHistory = new ArrayList<ActivityRecord>();  
   
   /** 
    * Used for validating app tokens with window manager. 
    */  
   final ArrayList<IBinder> mValidateAppTokens = new ArrayList<IBinder>();  
   
   /** 
    * List of running activities, sorted by recent usage. 
    * The first entry in the list is the least recently used. 
    * It contains HistoryRecord objects. 
    */  
   final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<ActivityRecord>();  
   
   /** 
    * List of activities that are waiting for a new activity 
    * to become visible before completing whatever operation they are 
    * supposed to do. 
    */  
   final ArrayList<ActivityRecord> mWaitingVisibleActivities  
       = new ArrayList<ActivityRecord>();  
   
   /** 
    * List of activities that are ready to be stopped, but waiting 
    * for the next activity to settle down before doing so.  It contains 
    * HistoryRecord objects. 
    */  
   final ArrayList<ActivityRecord> mStoppingActivities  
       = new ArrayList<ActivityRecord>();  
   
   /** 
    * List of activities that are in the process of going to sleep. 
    */  
   final ArrayList<ActivityRecord> mGoingToSleepActivities  
       = new ArrayList<ActivityRecord>();  
   /** 
    * When we are in the process of pausing an activity, before starting the 
    * next one, this variable holds the activity that is currently being paused. 
    */  
   ActivityRecord mPausingActivity = null;  
   
   /** 
    * This is the last activity that we put into the paused state.  This is 
    * used to determine if we need to do an activity transition while sleeping, 
    * when we normally hold the top activity paused. 
    */  
   ActivityRecord mLastPausedActivity = null;  
   
   /** 
    * Current activity that is resumed, or null if there is none. 
    */  
   ActivityRecord mResumedActivity = null;  
    
   /** 
    * This is the last activity that has been started.  It is only used to 
    * identify when multiple activities are started at once so that the user 
    * can be warned they may not be in the activity they think they are. 
    */  
   ActivityRecord mLastStartedActivity = null;  
   
   /** 
   * Set to indicate whether to issue an onUserLeaving callback when a 
    * newly launched activity is being brought in front of us. 
    */  
   boolean mUserLeaving = false;  
   
   ActivityStack(ActivityManagerService service, Context context, boolean mainStack) {  
     mService = service;  
     mContext = context;  
     mMainStack = mainStack;  
     ...  
   }  
   ...  
 }  

4.2 家族图谱

5. ProcessRecord

记录了一个进程的相关信息。

5.1 类中关键信息

 /** 
  * Full information about a particular process that 
  * is currently running. 
  */  
 class ProcessRecord {  
   final ApplicationInfo info; // all about the first app in the process  
   final boolean isolated;   // true if this is a special isolated process  
   final int uid;        // uid of process; may be different from 'info' if isolated  
   final int userId;       // user of process.  
   final String processName;   // name of the process  
   
   IApplicationThread thread;  // the actual proc...  may be null only if  
                 // 'persistent' is true (in which case we  
                 // are in the process of launching the app)  
                 // 是 ApplicationThread 对象的远程接口,  
                 // 通过此接口通知 Activity 进入对应的状态  
                   
   int pid;          // The process of this application; 0 if none  

   ApplicationInfo instrumentationInfo; // the application being instrumented  
   
   BroadcastRecord curReceiver;// receiver currently running in the app  
  
   // contains HistoryRecord objects  
   final ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();  
   
   // all ServiceRecord running in this process  
   final HashSet<ServiceRecord> services = new HashSet<ServiceRecord>();  
   
   // services that are currently executing code (need to remain foreground).  
   final HashSet<ServiceRecord> executingServices  
        = new HashSet<ServiceRecord>();  
   
   // All ConnectionRecord this process holds  
  final HashSet<ConnectionRecord> connections  
       = new HashSet<ConnectionRecord>();  
   
   // all IIntentReceivers that are registered from this process.  
   final HashSet<ReceiverList> receivers = new HashSet<ReceiverList>();  
   
   // class (String) -> ContentProviderRecord  
   final HashMap<String, ContentProviderRecord> pubProviders  
       = new HashMap<String, ContentProviderRecord>();   
   
   // All ContentProviderRecord process is using  
   final ArrayList<ContentProviderConnection> conProviders  
       = new ArrayList<ContentProviderConnection>();  
     
   boolean persistent;     // always keep this application running?  
   boolean crashing;       // are we in the process of crashing?  
   Dialog crashDialog;     // dialog being displayed due to crash.  
   boolean notResponding;    // does the app have a not responding dialog?  
   Dialog anrDialog;       // dialog being displayed due to app not resp.  
   boolean removed;      // has app package been removed from device?  
   boolean debugging;      // was app launched for debugging?  
   boolean waitedForDebugger;  // has process show wait for debugger dialog?  
   Dialog waitDialog;      // current wait for debugger dialog  
   
   ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, IApplicationThread _thread,  
       ApplicationInfo _info, String _processName, int _uid) {  
     batteryStats = _batteryStats;  
     info = _info;  
     isolated = _info.uid != _uid;  
     uid = _uid;  
     userId = UserHandle.getUserId(_uid);  
     processName = _processName;  
     pkgList.add(_info.packageName);  
     thread = _thread;  
     maxAdj = ProcessList.HIDDEN_APP_MAX_ADJ;  
    hiddenAdj = clientHiddenAdj = emptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;  
     curRawAdj = setRawAdj = -100;  
     curAdj = setAdj = -100;  
     persistent = false;  
     removed = false;  
   }  
   ...  
 }  

5. 2 家族图谱

6. IApplicationThread 接口 AMS->Application

IApplicationThread 为 AMS 作为客户端访问 Application 服务器端的 Binder 接口。当创建 Application 时,将把此 Binder 对象传递给 AMS,然后 AMS 把它保存在 mProcessNames.ProcessRecord.thread 中。当需要通知 Application 工作时,则调用 IApplicationThread 中对应的接口函数。

其相互关系如下图所示:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文