Android 7.1 APP 启动流程分析

本文是基于 Android 7.1 系统进行探讨的.

我们都知道Launcher 其实也是一个APP ,安装好的应用的快捷方式都被放在了Launcher中.很多的厂家或者厂商都在定制自己的Launcher,目前我们知道Android现在使用的是Launcher3的版本,

总体创建流程如下

下图是应用层创建Activity的过程

我们可以在如下路径找到Launcher.java

packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

可以查看到 Launcher.java 中的方法就是创建图标的方法. 由此可以知道 图标的点击事件放在了本 favorite.setOnClickListener(this);

    public View createShortcut(ViewGroup parent, ShortcutInfo info) {
        BubbleTextView favorite = (BubbleTextView) getLayoutInflater().inflate(R.layout.app_icon,
                parent, false);
        favorite.applyFromShortcutInfo(info, mIconCache);
        favorite.setCompoundDrawablePadding(mDeviceProfile.iconDrawablePaddingPx);
        favorite.setOnClickListener(this);
        favorite.setOnFocusChangeListener(mFocusHandler);
        return favorite;
    }

我们查看到 Launcher.java 中的onClick方法 可以查看到 如下监听时间发现走的是 onClickAppShortcut(v); 

  public void onClick(View v) {
        // Make sure that rogue clicks don't get through while allapps is launching, or after the
        // view has detached (it's possible for this to happen if the view is removed mid touch).
........省略代码.....

        Object tag = v.getTag();
        if (tag instanceof ShortcutInfo) {
            //启动桌面图标
            onClickAppShortcut(v);
        } else if (tag instanceof FolderInfo) {
            if (v instanceof FolderIcon) {
                onClickFolderIcon(v);
            }
        } else if ((FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && v instanceof PageIndicator) ||
                (v == mAllAppsButton && mAllAppsButton != null)) {
            onClickAllAppsButton(v);
        } else if (tag instanceof AppInfo) {
            startAppShortcutOrInfoActivity(v);
        } else if (tag instanceof LauncherAppWidgetInfo) {
            if (v instanceof PendingAppWidgetHostView) {
                onClickPendingWidget((PendingAppWidgetHostView) v);
            }
        }
    }

查看onClickAppShortcut(v); 我们可以查看到调用的是   startAppShortcutOrInfoActivity(v); 我们继续查看 

   protected void onClickAppShortcut(final View v) {
        if (LOGD) Log.d(TAG, "onClickAppShortcut");
...........省略代码........

        // Start activities
        startAppShortcutOrInfoActivity(v);
    }

查看 startAppShortcutOrInfoActivity(v);方法

   private void startAppShortcutOrInfoActivity(View v) {
        ItemInfo item = (ItemInfo) v.getTag();
        Intent intent = item.getIntent();
        if (intent == null) {
            throw new IllegalArgumentException("Input must have a valid intent");
        }
        //启动Activity 
        boolean success = startActivitySafely(v, intent, item);
        getUserEventDispatcher().logAppLaunch(v, intent);

        if (success && v instanceof BubbleTextView) {
            mWaitingForResume = (BubbleTextView) v;
            mWaitingForResume.setStayPressed(true);
        }
    }

紧接着我们查看到 startActivitySafely 方法被调用startActivity 方法也就是调用的我们Activity.java中的方法

    public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
         .....省略代码......
        // Prepare intent
        //添加  FLAG_ACTIVITY_NEW_TASK
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (v != null) {
            intent.setSourceBounds(getViewBounds(v));
        }
        .....省略代码......
        //启动 Activity
         startActivity(intent, optsBundle);
       
        return false;
    }

我们从startActivitySafely 可以看到 添加了 Intent.FLAG_ACTIVITY_NEW_TASK 这个Flag 也调用了 startActivity 这个方法.到这里就又回到了Activity的startActivity()方法,也就是Activity的启动流程

frameworks/base/core/java/android/app/Activity.java
    public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
        ......省略代码.....
        Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                        this, mMainThread.getApplicationThread(), mToken, this,
                        intent, -1, options, user);
       ......省略代码.....
        cancelInputsAndStartExitTransition(options);
    }

 查看到调用到了Instrumentation.java 中的 execStartActivity 方法

frameworks/base/core/java/android/app/Instrumentation.java
    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
   ..... 省略代码 ....
        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;
    }

  查看到调用到了ActivityManagerService.jav 中的 startActivity 方法

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }
    @Override
    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) {
        enforceNotIsolatedCaller("startActivity");
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null);
    }
frameworks\base\services\core\java\com\android\server\am\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) {
            ....省略代码....
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                    inTask);
    }
   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) {
        ....省略代码.....
        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;
    }
frameworks\base\services\core\java\com\android\server\am\ActivityStack.java
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
                ....省略代码....
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
                ....省略代码....
        return START_SUCCESS;
    }
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        ...省略代码...
    }
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
            ...省略代码...
            result = resumeTopActivityInnerLocked(prev, options);
            ...省略代码...
    }

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
       ...省略代码...
       mStackSupervisor.startSpecificActivityLocked(next, true, false);
       ...省略代码...
        return true;
    }

到此处我们可以查看到如果应用已经启动 就直接开始创建Activity进行底层通讯.如果进程未启动需要创建进行 

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        
        if (app != null && app.thread != null) {
            //进程已经创建
            try {
                //创建Activity
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }
        //进程不存在需要先创建进程
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, 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);
            ...省略代码...
    }
frameworks/base/core/java/android/app/IApplicationThread.java
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) throws RemoteException;
frameworks/base/core/java/android/app/ApplicationThreadNative.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) throws RemoteException {
             ...省略代码...
        mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
            ...省略代码...
    }
    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        ...省略代码...
        case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
        {
           ...省略代码...
            //调用的是 ActivityThread.java中的 内部类 ApplicationThread
            //scheduleLaunchActivity
            scheduleLaunchActivity(intent, b, ident, info, curConfig, overrideConfig, compatInfo,
                    referrer, voiceInteractor, procState, state, persistentState, ri, pi,
                    notResumed, isForward, profilerInfo);
           ...省略代码...
        }
       ...省略代码...
    }
frameworks/base/core/java/android/app/ActivityThread.java
 @Override
        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) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            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) {
        
        ...省略代码...
        //不可见 on
        Activity a = performLaunchActivity(r, customIntent);
        ...省略代码...
        //Activity可见 
        handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
    }

进程不存在的情况

mService的类型是ActivityManagerService(AMS),我们来看ActivityManagerService的startProcessLocked()方法:

private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
                                   ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
                                   String seInfo, String requiredAbi, String instructionSet, String invokeWith,
                                   long startTime) {
    // ...
    final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
            app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
            requiredAbi, instructionSet, invokeWith, app.startTime);
    // ...
}

经过一系列调用最终执行了Process.start()方法:

public static final ProcessStartResult start(final String processClass,
                                             final String niceName,
                                             int uid, int gid, int[] gids,
                                             int runtimeFlags, int mountExternal,
                                             int targetSdkVersion,
                                             String seInfo,
                                             String abi,
                                             String instructionSet,
                                             String appDataDir,
                                             String invokeWith,
                                             String[] zygoteArgs) {
    return zygoteProcess.start(processClass, niceName, uid, gid, gids,
            runtimeFlags, mountExternal, targetSdkVersion, seInfo,
            abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}

接着又调用了ZygoteProcess的start()方法:

public final Process.ProcessStartResult start(final String processClass,
                                              final String niceName,
                                              int uid, int gid, int[] gids,
                                              int runtimeFlags, int mountExternal,
                                              int targetSdkVersion,
                                              String seInfo,
                                              String abi,
                                              String instructionSet,
                                              String appDataDir,
                                              String invokeWith,
                                              String[] zygoteArgs) {
....略代码...
        return startViaZygote(processClass, niceName, uid, gid, gids,
                runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
                zygoteArgs);
....略代码...
  
}

private Process.ProcessStartResult startViaZygote(final String processClass,
                                                  final String niceName,
                                                  final int uid, final int gid,
                                                  final int[] gids,
                                                  int runtimeFlags, int mountExternal,
                                                  int targetSdkVersion,
                                                  String seInfo,
                                                  String abi,
                                                  String instructionSet,
                                                  String appDataDir,
                                                  String invokeWith,
                                                  boolean startChildZygote,
                                                  String[] extraArgs)
        throws ZygoteStartFailedEx {
    ....略代码...
    return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}

private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
        ZygoteState zygoteState, ArrayList<String> args)
        throws ZygoteStartFailedEx {
   ....略代码...
    for (int i = 0; i < sz; i++) {
        String arg = args.get(i);
        writer.write(arg);
        writer.newLine();
    }
....略代码...
    writer.flush();
....略代码...
    result.pid = inputStream.readInt();
    result.usingWrapper = inputStream.readBoolean();
....略代码...
    return result;
}

这里又是经过了一系列的调用,最终执行了zygoteSendArgsAndGetResult()方法,该方法的作用就是创建App进程。关于App进程的创建,我粗略地阅读了一下网上的相关文章,简单介绍一下,Android中有一个重要的进程Zygote,翻译为受精卵进程,所有的应用程序进程都是通过Zygote进程fork得来的。流程简单来说就是通过Binder请求AMS进程,然后AMS再发送Socket消息给Zygote进程,最后统一由Zygote进程fork出应用进程

进程创建完成后,就会执行ActivityThread的main()方法,它是应用程序的入口方法之后就是和ActivityManagerService.java 的一些交互工作.

public static void main(String[] args) {
    ...省略代码...
    // 创建主线程Looper
    Looper.prepareMainLooper();
    ...省略代码...
    // 核心代码
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
    ...省略代码...
      // 开启消息循环
    Looper.loop();
     ...省略代码...
}

猜你喜欢

转载自blog.csdn.net/ChaoLi_Chen/article/details/106786529