(Android11.0)Android启动过程的深度挖掘(上篇)

Posted 丶笑看退场

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(Android11.0)Android启动过程的深度挖掘(上篇)相关的知识,希望对你有一定的参考价值。

前言

Activity的启动分为两种,一个是根Activity的启动过程,另一种是普通Activity的启动过程。而第一种就是指一个app启动的过程,普通Activity就是指在应用中调用startActivity的过程。

拿根Activity的启动来讲比较全面,也很好的理解android的整个启动过程。可以分为三个部分Launcher请求过程AMS到ApplicationThread的调用过程ActivityThread启动Activity

把android7、8、9的启动过程看了一遍,那我们现在就基于android 11源码再来分析一遍,要选就选最新的来分析,设计思想都是通的。

Launcher启动过程

当点击app图标后,就会调用launcherstartActivitySafely方法,内部又会调用startActivity方法。

## Launcher.java
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) 
     ...
       //设置在新的任务栈中启动
     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     if (v != null) 
         intent.setSourceBounds(getViewBounds(v));
     
     try 
         if (Utilities.ATLEAST_MARSHMALLOW
                 && (item instanceof ShortcutInfo)
                 && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
                  || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
                 && !((ShortcutInfo) item).isPromise()) 
             startShortcutIntentSafely(intent, optsBundle, item);
          else if (user == null || user.equals(Process.myUserHandle())) 
           //调用startActivity来启动页面
             startActivity(intent, optsBundle);//2
          else 
             LauncherAppsCompat.getInstance(this).startActivityForProfile(
                     intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
         
         return true;
      catch (ActivityNotFoundException|SecurityException e) 
         Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
         Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
     
     return false;
 

这其中会设置intent的Flag为Intent.FLAG_ACTIVITY_NEW_TASK开启一个新的任务栈,真正调用的会再activitystartActivity方法。

### Activity
      public void startActivity(Intent intent, @Nullable Bundle options) 
        ......
          
        if (options != null) 
            startActivityForResult(intent, -1, options);
         else 
            //我们希望通过此调用与可能已覆盖该方法的应用程序兼容。
            startActivityForResult(intent, -1);
        
    

都会走到startActivityForResult方法里,第二个参数为-1,表示Launcher不需要知道Activity启动的结果。

### Activitu.java   
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) 
        if (mParent == null) 
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
           ......

            cancelInputsAndStartExitTransition(options);
         else 
            ......
        
    

由于是第一次创建mParent = null,内部会调用了InstrumentationexecStartActivity方法。Instrumentation具有跟踪application及生命周期的方法。

### Instrumentation    
public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) 
        ......
       
        try 
            intent.migrateExtraStreamToClipData(who);
            intent.prepareToLeaveProcess(who);
            int result = ActivityTaskManager.getService().startActivity(whoThread,
                    who.getBasePackageName(), who.getAttributionTag(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()), token,
                    target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
         catch (RemoteException e) 
            throw new RuntimeException("Failure from system", e);
        
        return null;
    

(ActivityTaskManager andrrod 10.0新增方法,getService这个是android 8.0后新增方法)

首先会调用ActivityTaskManager.getService()获取AMS的代理对象,接着调用startActivity方法、那又是如何获取到AMS的代理对象的呢?

### ActivityTaskManager
 public static IActivityTaskManager getService() 
        return IActivityTaskManagerSingleton.get();
    
    
 private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
            new Singleton<IActivityTaskManager>() 
                @Override
                protected IActivityTaskManager create() 
                  //获取到ACTIVITY_TASK_SERVICE的引用,也就是IBinder类型的ATMS的引用
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                  //要实现进程间通信,服务端也就是AMS只需要继承IActivityManager.Stub类并实现相应的方法就可以了。
                    return IActivityTaskManager.Stub.asInterface(b);
                
            ;

可以看到这里获取了一个跨进程的服务,也就是**ActivityTaskManagerService**,它继承于IActivityTaskManager.Stub,是个Binder对象。知道了这是什么后,就可以回到InstrumentationexecStartActivity方法往下看。

ATMS到ApplicationThread过程

接着我们就进到了系统提供的服务ATMS中,接着是ATMS到ApplicationThread的调用流程,时序图如图:

接下来继续分析,已经走到了ATMS的startActivity方法。

 ### ActivityTaskManagerService 
 public final int startActivity(IApplicationThread caller, String callingPackage,
            String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
            Bundle bOptions) 
   //可以发现startActivityAsUser方法比startActivity方法多了一个参数UserHandle.getCallingUserId(),这个方法会获得调用者的UserId
   //AMS会根据这个UserId来确定调用者的权限。
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    

 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
            String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
            Bundle bOptions, int userId) 
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    

  private int startActivityAsUser(IApplicationThread caller, String callingPackage,
            @Nullable String callingFeatureId, Intent intent, String resolvedType,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) 
        assertPackageMatchesCallingUid(callingPackage);
    //判断调用者进程是否被隔离   
        enforceNotIsolatedCaller("startActivityAsUser");

    //检查调用者权限
        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // 获取ActivityStart对象,并在最后excute启动activity.
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setCallingFeatureId(callingFeatureId)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setUserId(userId)
                .execute();

    

经过一层套一层地调用,来到了最后,通过etActivityStartController().obtainStarter获取ActivityStart对象,并在最后excute方法来启动activity。

### ActivityStarter
//执行开始活动的请求
int execute() 
        try 
            ......

            if (mRequest.activityInfo == null) 
                mRequest.resolveActivity(mSupervisor);
            

            int res;
            synchronized (mService.mGlobalLock) 
                final boolean globalConfigWillChange = mRequest.globalConfig != null
                        && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
                final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
              ......

                final long origId = Binder.clearCallingIdentity();

                res = resolveToHeavyWeightSwitcherIfNeeded();
                if (res != START_SUCCESS) 
                    return res;
                
              
              //执行启动接界面请求
                res = executeRequest(mRequest);

                Binder.restoreCallingIdentity(origId);

                ......
                return getExternalResult(mRequest.waitResult == null ? res
                        : waitForResult(res, mLastStartActivityRecord));
            
         finally 
            onExecutionComplete();
        
    

(executeRequest是Android11新增方法)

再来看下executeRequest方法,关注下主要的方法:

### ActivityStarter.java
  
  //执行活动启动请求,开启活动启动之旅。首先是执行几个初步检查。正常的活动启动流程会经过
  private int executeRequest(Request request) 
  .....
  mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
                restrictedBgActivity, intentGrants);

        if (request.outActivity != null) 
            request.outActivity[0] = mLastStartActivityRecord;
        

        return mLastStartActivityResult;

里面又调用startActivityUnchecked方法。

###   ActivityStarter
//主要处理栈管理相关的逻辑
//初步检查并确认调用者拥有执行此操作所需的权限后开始一项活动
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, Task inTask,
                boolean restrictedBgActivity, NeededUriGrants intentGrants) 
        int result = START_CANCELED;
        final ActivityStack startedActivityStack;
        try 
            mService.deferWindowLayout();
            Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
         finally 
            Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
            startedActivityStack = handleStartResult(r, result);
            mService.continueWindowLayout();
        

        postStartActivityProcessing(r, result, startedActivityStack);

        return result;
    

startActivityUnchecked主要处理栈管理相关的逻辑。之后调用了startActivityInner方法,最后调用到了RootWindowContainerresumeFocusedStacksTopActivities方法。

### ActivityStarter
  //启动活动并确定活动是否应添加到现有任务的顶部或向现有活动传递新意图。还将活动任务操作到请求的或有效的堆栈显示上。
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity, NeededUriGrants intentGrants) 
          
  ......
    
  if (newTask) 
            final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                    ? mSourceRecord.getTask() : null;
    //内部会创建一个新的Activity任务栈
            setNewTask(taskToAffiliate);
            if (mService.getLockTaskController().isLockTaskModeViolation(
                    mStartActivity.getTask())) 
                Slog.e(TAG, "Attempted Lock Task Mode violation mStartActivity=" + mStartActivity);
                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
            
         else if (mAddingToTask) 
            addOrReparentStartingActivity(targetTask, "adding to task");
        
  
  ......
    //主要关注这行代码
    mRootWindowContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);  1
  ......
    return START_SUCCESS;
            

RootWindowContainer是Android10新增的类

RootWindowContainer分担了之前ActivityStackSupervisor的部分功能。resumeFocusedStacksTopActivities内部又会调用ActivityStackresumeTopActivityUncheckedLocked方法,接着我们进去看下这个方法。

### ActivityStack
      boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) 
        if (mInResumeTopActivity) 
            // 如果顶部Activity正在执行则不处理
            return false;
        

        boolean result = false;
        try 
            // Protect against recursion.
            mInResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);

            //恢复top Activity时,可能需要暂停top Activity
            final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
            if (next == null || !next.canTurnScreenOn()) 
                checkReadyForSleep();
            
         finally 
            mInResumeTopActivity = false;
        

        return result;
    

接着跳到resumeTopActivityInnerLocked方法里来看:

### ActivityStack
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) 
  ......
  if (mResumedActivity != null) 
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
    //当上一个界面活动,则会暂停上个界面
            pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);
        
  
  .......
  final ClientTransaction transaction =
                        ClientTransaction.obtain(next.app.getThread(), next.appToken);
  .......
  //启动了的Activity就发送ResumeActivityItem事务给客户端了
  transaction.setLifecycleStateRequest(
                        ResumeActivityItem(Android11.0)App启动过程的深度挖掘(下篇)

(Android11.0)App启动过程的深度挖掘(下篇)

Android 10.0 11.0 12.0 启动模拟器教程

Android 10.0 11.0 12.0 启动模拟器教程

Android 10.0 11.0 12.0 启动模拟器教程

Android 11.0 启动box功能