Android 应用启动流程

手机应用在 Launcher 上分布, 当掉级某一个apk时, 该Apk将启动, 现在就来针对 Android N的 Launcher3 为切入点, 进行分析.

分析过程参考老罗的的博客


        应用的快捷图标在 Launcher 界面上进行显示。 当点击某个图标时,对于 Launcher 而言, 这是个点击事件, 所以会继承一个点击事件的接口。因为 Launcher 也是会显示界面, 其必然会继承至 Activity. Launcher 的入口类: Launcher.java.
所以在进行点击 Launcher 图标时, 必然需要判断其类型, 然后再做反应. 对于点击应用图标, 其在桌面上显示为快捷图标. 即点击事件:

  • Launcher.java
    //Launches the intent referred by the clicked shortcut.
    //启动快捷图标.
    public void onClick(View v) {
        ...
        Object tag = v.getTag();
        if (tag instanceof ShortcutInfo) {
            onClickAppShortcut(v);
        } else if (tag instanceof FolderInfo) {
            if (v instanceof FolderIcon) {
                onClickFolderIcon(v);
            }
        } 
        ....
    }
    
    
    protected void onClickAppShortcut(final View v) {
        ...
        // Start activities
        startAppShortcutOrInfoActivity(v);

        if (mLauncherCallbacks != null) {
            mLauncherCallbacks.onClickAppShortcut(v);//后续分析,回调原因
        }
    }
    
    @Thunk void startAppShortcutOrInfoActivity(View v) {
        Object tag = v.getTag();
        final ShortcutInfo shortcut;
        final Intent intent;
        //获取shortcut的位置.
        if (tag instanceof ShortcutInfo) {
            shortcut = (ShortcutInfo) tag;
            intent = shortcut.intent;
            int[] pos = new int[2];
            //计算图标的位置, 并将值赋给 pos 数组.
            v.getLocationOnScreen(pos);
            //利用图标的位置信息, 构建一个矩形, 并保存在 Intent 中
            intent.setSourceBounds(new Rect(pos[0], pos[1],
                    pos[0] + v.getWidth(), pos[1] + v.getHeight()));

        } 
        ...
        boolean success = startActivitySafely(v, intent, tag); //启动
        mStats.recordLaunch(v, intent, shortcut);//记录, 稍后分析
    }
    
    //判断是否在安全模式下启动, 非系统级应用不能再安全模式下启动
    public boolean startActivitySafely(View v, Intent intent, Object tag) {
        ...
        try {
            success = startActivity(v, intent, tag);//继续
        } catch (ActivityNotFoundException e) {
          ...
        }
        return success;
    }
    
    
    private boolean startActivity(View v, Intent intent, Object tag) {
        //设置栈标志位, 开启一个新栈. 
        //所以每个应用都在不同的栈中
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try {
            ...
            if (user == null || user.equals(UserHandleCompat.myUserHandle())) {
                StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
                try {
                   ...
                    // Could be launching some bookkeeping activity
                    //optsBundle 动画数据. 转换为bundle数据进行传输
                    startActivity(intent, optsBundle);
                } finally {
                    ....
                }
                ...
            } 
            return true;
        } catch (SecurityException e) {
            ...
        }
        return false;
    }

因为 Launcher 继承了 Activity. startActivity(intent, optsBundle) 由 Activity 的实现题在 Activity,java. 现在就转入到 Activity(framework下)

  • Activity.java
public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

这里认为 options == null, 最终都会走这里

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) { //对于新开启的apk, mParent == null
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            ...
        }
        ...
    }
  1. mMainThread.getApplicationThread(): 应用进程.返回为了 ApplicationThread 类对象, 该类继承与 ApplicationThreadNative, 是一个 Binder 的抽象类. 表示该 Activity 运行在主进程上.
  2. Instrumentation.ActivityResult: 用于描述 Activity 的执行结果. 
  3. Instrumentation:测试应用的基类, 用来监控应用程序和系统的交互.
  • Instrumentation.java
    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        ...
        if (mActivityMonitors != null) {//当开启一个Activity, 监控器就会被打开.
        ...
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), 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;
    }
```

这里, ActivityManagerNative.getDefault() 返回了是 IActivityManager, 这是 ActivityManagerService 的远程接口.

```
int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
                        

# ActivityManagerNative$ActivityManagerProxy
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
        ...
 
        return result;
    }

至此, 进入到 ActivityManagerService, 先来看看有哪几个参数问 null 或 0. 

startFlags=0; resultWho = null; profilerInfo = null

  • ActivityManagerService
   public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        //针对不同的 user 的 ID 进行处理了.   
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }
    
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        ...
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho/*null*/, requestCode/*0*/, startFlags,
                profilerInfo/*null*/, null, null, bOptions, false, userId, null, null);
    }

这里向下分别传递了几个空参数.

 callingUid = -1; voiceSession = null; voiceInteractor = null;
 outResult = null;  config = null

从这里可以看出, 如果应用可以正常启动 那么 ActivityManagerService.startActivityAsUser() 将返回 ActivityManager.START_SUCCESS.  

  • ActivityStarter.java
    final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
            Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask) {
        // Refuse possible leaked file descriptors
        synchronized (mService) {
            ...
            
            final ActivityRecord[] outRecord = new ActivityRecord[1];
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession/*null*/, voiceInteractor/*null*/,
                    resultTo, resultWho/*null*/, requestCode/*0*/, callingPid,
                    callingUid/*-1*/, callingPackage, realCallingPid, realCallingUid, startFlags/*0*/,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                    inTask);
                ....
            }
            ...
            return res;
        }
    }
    
    
    //如果 launcher 应用成功, 那么将返回 ActivityManager.START_SUCCESS.
    final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask) {
            
        int err = ActivityManager.START_SUCCESS;
        ...
        
        try {
            mService.mWindowManager.deferSurfaceLayout();
            
            err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                    true, options, inTask);
        } finally { 
            mService.mWindowManager.continueSurfaceLayout();
        }
        postStartActivityUncheckedProcessing(r, err, stack.mStackId, mSourceRecord, mTargetStack);
        return err;
    }

现在主要看看

    err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, 
    true, options, inTask);

r: ActivityRecord 对象. 表示一个在栈中的的Activity实例. 

sourceRecord: ActivityRecord 对象.

voiceSession: null

voiceInteractor: null
startFlags: 0

options, inTask: 都是从上传过来.

  • ActivityStarter.java
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
        ...
       if (dontStart) {
            ActivityStack.logStartActivity(AM_NEW_INTENT, top, top.task);
            // For paranoia, make sure we have correctly resumed the top activity.
            topStack.mLastPausedActivity = null;
            if (mDoResume) {
                mSupervisor.resumeFocusedStackTopActivityLocked();
            }
        }
    }

mSupervisor.resumeFocusedStackTopActivityLocked();

此时跳转到了ActivityStackSupervisor.

  • ActivityStackSupervisor.java
    boolean resumeFocusedStackTopActivityLocked() {
        return resumeFocusedStackTopActivityLocked(null, null, null);
    }
    
    //三个参数都是传进来的是 null.
    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        }
        return false;
    }

又重新进入到了 ActivityStatck


 ActivityStack.java 

  boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options); //here
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }
    
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        ...
        mStackSupervisor.startSpecificActivityLocked(next, true, false);
        ...
    }


此时, 将三个参数传到下一步:

  • ActivityStackSupervisor.java
    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        
        ...
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }


返回到:

  • ActivityManagerService.java
    final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }
    
    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
        
        ...
        checkTime(startTime, "startProcess: stepping in to startProcess");
        startProcessLocked(
                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
        checkTime(startTime, "startProcess: done starting proc!");
        return (app.pid != 0) ? app : null;
    }
    
    private final void startProcessLocked(ProcessRecord app,
            String hostingType, String hostingNameStr) {
        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
                null /* entryPoint */, null /* entryPointArgs */);
    }

    
    private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        ...
        try {
            ...
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            checkTime(startTime, "startProcess: asking zygote to start proc");
            android.util.Log.d("@ying","ActivityManagerService.startProcessLocked->Process.start: to ActivityThread.main");
            Process.ProcessStartResult startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                    app.info.dataDir, entryPointArgs);
            
            ...
            }
        }
    }

跳转到

  • ActivityThread.java
    public static void main(String[] args) {
        ...
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        ...
    }
    
    private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ...
            try {
            ...
                mgr.attachApplication(mAppThread);
            } 
        } 
        ...
    }


再次回到 ActivityManagerService

  • ActivityManagerService.java
    public final void attachApplication(IApplicationThread thread) {
    
        synchronized (this) {
            ...
            attachApplicationLocked(thread, callingPid);
            ...
        }
    }
    
    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
        ...
        
        if (normalMode) {
            try 
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } 
        }
      ...
    }


        
再次到 ActivityStackSupervisor

  •  ActivityStackSupervisor.java
    public final void attachApplication(IApplicationThread thread) {
    
        synchronized (this) {
            ...
            attachApplicationLocked(thread, callingPid);
            ...
        }
    }
    
    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
        ...
        
        if (normalMode) {
            try 
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } 
        }
      ...
    }

    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        ...
        if (realStartActivityLocked(hr, app, true, true)) {
            didSomething = true;
        }
    }
    
    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException {
    ...
    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);//@ying here
    ...
    }

此时步骤又到了

  • ActivityThread.java
    public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            sendMessage(H.LAUNCH_ACTIVITY, r);
    }
    
   //发送到子线程中去执行
   public void handleMessage(Message msg) {
           
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
            }
        }
    }
    
    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ...
        Activity a = performLaunchActivity(r, customIntent);
        ...
    }
    
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...

        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } 
        ...
        activity.mCalled = false;
        if (r.isPersistable()) {
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
            mInstrumentation.callActivityOnCreate(activity, r.state);
        }
        return activity;
    }

跳转

  • Instrumentation
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        postPerformCreate(activity);
    }

猜你喜欢

转载自blog.csdn.net/dec_sun/article/details/82705702