美文网首页
Binder篇_03Activity启动流程学习

Binder篇_03Activity启动流程学习

作者: 冉桓彬 | 来源:发表于2019-04-13 21:04 被阅读0次

目标:

1. system_server进程的创建;
2. AMS的创建以及核心服务的注册;
3. App进程何时创建;
4. App进程的Binder线程何时创建;
5. App线程何时创建;
6. Application.attachBaseContext()方法为什么不会ANR;
7. Activity之间通信时关于序列化;
8. Activity之间传值大小限制;

围绕这几个问题分几篇笔记进行分析;

这篇笔记主要包括以下几个点

1. app进程的创建;
2. app进程对应的binder线程的创建;
3. app主线程的创建;

涉及到的源码路径如下

源码 链接
Launcher.java https://www.androidos.net.cn/android/6.0.1_r16/xref/packages/apps/Launcher2/src/com/android/launcher2/Launcher.java
ActivityManagerService.java https://www.androidos.net.cn/android/6.0.1_r16/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
SystemServer.java https://www.androidos.net.cn/android/6.0.1_r16/xref/frameworks/base/services/java/com/android/server/SystemServer.java
ProcessState.cpp https://www.androidos.net.cn/android/6.0.1_r16/xref/frameworks/native/libs/binder/ProcessState.cpp
app_main.cpp https://www.androidos.net.cn/android/6.0.1_r16/xref/frameworks/base/cmds/app_process/app_main.cpp

参考文章

startActivity启动过程分析
Android四大组件与进程启动的关系
理解Android进程创建流程
ApplicationThreadNative.java
ActivityManagerNative.java
ActivityManagerService.java
ActivityThread.java
理解Application创建过程

网上截图
下面这个流程图主要是方法栈和进程转换的流程图, 为了方便画图,
每个方法都没有进行说明, 下边在对每个进程分别分析时的流程图会有注释;

一、Launcher进程

1.1 Launcher.onClick
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) {
        // Open shortcut
        final Intent intent = ((ShortcutInfo) tag).intent;
        int[] pos = new int[2];
        v.getLocationOnScreen(pos);
        intent.setSourceBounds(new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight()));
        // 启动Activity;
        boolean success = startActivitySafely(v, intent, tag);
        if (success && v instanceof BubbleTextView) {
            mWaitingForResume = (BubbleTextView) v;
            mWaitingForResume.setStayPressed(true);
        }
    } else if (tag instanceof FolderInfo) {
        if (v instanceof FolderIcon) {
            FolderIcon fi = (FolderIcon) v;
            handleFolderClick(fi);
        }
    } else if (v == mAllAppsButton) {
        if (isAllAppsVisible()) {
            showWorkspace(true);
        } else {
            onClickAllAppsButton(v);
        }
    }
}
1.2 Launcher.startActivitySafely
boolean startActivitySafely(View v, Intent intent, Object tag) {
    boolean success = false;
    success = startActivity(v, intent, tag);
    return success;
}
1.3 Launcher.startActivity
// 这里的调用链直接忽略掉, 调用直接进入Activity.startActivity
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);
    }
}

public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        // 启动任务交给mInstrumentation处理
        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());
        }
        if (requestCode >= 0) {
            // If this start is requesting a result, we can avoid making
            // the activity visible until the result is received.  Setting
            // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
            // activity hidden during this time, to avoid flickering.
            // This can only be done when a result is requested because
            // that guarantees we will get information back when the
            // activity is finished, no matter what happens to it.
            mStartedActivity = true;
        }
        cancelInputsAndStartExitTransition(options);
        // TODO Consider clearing/flushing other event sources and events for child windows.
    } else {
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
            // Note we want to go through this method for compatibility with
            // existing applications that may have overridden it.
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}
1.4 Instrumentation.execStartActivity
public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    // 启动Activity交给AMN
    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);
    return null;
}
1.5 ActivityManagerNative.getDefault().startActivity
static public IActivityManager getDefault() {
    return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
    protected IActivityManager create() {
        // b指向的是BinderProxy;
        IBinder b = ServiceManager.getService("activity");
        // 返回am指向ActivityManagerProxy;
        IActivityManager am = asInterface(b);
        return am;
    }
};
1.6 ActivityManagerProxy.startActivity
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 {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IActivityManager.descriptor);
    data.writeStrongBinder(caller != null ? caller.asBinder() : null);
    data.writeString(callingPackage);
    intent.writeToParcel(data, 0);
    data.writeString(resolvedType);
    data.writeStrongBinder(resultTo);
    data.writeString(resultWho);
    data.writeInt(requestCode);
    data.writeInt(startFlags);
    if (profilerInfo != null) {
        data.writeInt(1);
        profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
    } else {
        data.writeInt(0);
    }
    if (options != null) {
        data.writeInt(1);
        options.writeToParcel(data, 0);
    } else {
        data.writeInt(0);
    }
    // 这个方法最终会触发system_server进程的AMS.onTransact方法的执行, 至于里面如何触发的,
    // 不进行理会, 逻辑非常复杂, 而且也没必要去理会;
    mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
    reply.readException();
    int result = reply.readInt();
    reply.recycle();
    data.recycle();
    return result;
}

二、system_server进程

2.1 ActivityManagerService.onTransact
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
    switch (code) {
        case START_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            String callingPackage = data.readString();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            IBinder resultTo = data.readStrongBinder();
            String resultWho = data.readString();
            int requestCode = data.readInt();
            int startFlags = data.readInt();
            ProfilerInfo profilerInfo = data.readInt() != 0 ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
            Bundle options = data.readInt() != 0 ? Bundle.CREATOR.createFromParcel(data) : null;
            int result = startActivity(app, callingPackage, intent, resolvedType,
                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
            reply.writeNoException();
            reply.writeInt(result);
            return true;
        }
    }
}
2.2 ActivityManagerService.startActivity
@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());
}
ActivityStackSupervisor.startActivityMayWait ->
ActivityStackSupervisor.startActivityLocked ->
ActivityStackSupervisor.startActivityUncheckedLocked ->
ActivityStackSupervisor.resumeTopActivitiesLocked ->
ActivityStackSupervisor.resumeTopActivityLocked ->
ActivityStack.resumeTopActivityLocked ->
ActivityStack.resumeTopActivityInnerLocked ->
  ActivityStackSupervisor.pauseBackStacks ->
  ActivityStack.startPausingLocked ->
  ActivityStack.completePauseLocked ->
ActivityStackSupervisor.startSpecificActivityLocked ->
  ActivityManagerService.startProcessLocked(开始为目标App创建进程)
2.3 ActivityManagerService.startProcessLocked
private final void startProcessLocked() { 
    if (entryPoint == null) entryPoint = "android.app.ActivityThread";
    // 1. 这里会为目标App创建进程, 进程创建完成之后会回调ActivityThread.main方法;
    //    当前进程为system_server进程, 此时是由system_server进程向Zygote进程发起请求
    // 2. Zygote.forkAndSpecialize()为目标App创建进程;
    Process.start(entryPoint...);
} 
三、Zygote进程
3.1 ZygoteConnection.runOnce
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
    // 创建目标App进程;
    pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
                    parsedArgs.appDataDir);
    if (pid == 0) {
        // in child
        IoUtils.closeQuietly(serverPipeFd);
        serverPipeFd = null;
        // 创建完App进程以后, 还是进入到目标App进程中;
        handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
        // should never get here, the child is expected to either
        // throw ZygoteInit.MethodAndArgsCaller or exec().
        return true;
    }
}

四、目标App进程

4.1 ZygoteConnection.handleChildProc
private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr) {
    // 这里会创建一个Binder线程;
    RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null);
}
4.2 RuntimeInit.zygoteInit
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
    commonInit();
    // 这里创建App进程的Binder线程;
    nativeZygoteInit();
    applicationInit(targetSdkVersion, argv, classLoader);
}
4.3 AndroidRuntime.com_android_internal_os_RuntimeInit_nativeZygoteInit
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    // 触发app_main.onZygoteInit()方法的执行;
    gCurRuntime->onZygoteInit();
}
4.4 app_main.onZygoteInit
virtual void onZygoteInit()
{
    sp<ProcessState> proc = ProcessState::self();
    ALOGV("App process: starting thread pool.\n");
    // 知道这里是创建Binder线程即可, 至于线程创建细节, 感觉没必要知道;
    // 内部就是调用了new PoolThread().start()操作;
    proc->startThreadPool();
}
4.5 RuntimeInit.applicationInit
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
    // 之类args.startClass为何会指向的是ActivityThread, 在下面一个篇幅中进行分析;
    // 分析完成之后, 以后只需要记住Zygote进程创建完目标App进程并为目标App进程创建Binder线程以后, 会进入到
    // 目标App的ActivityThread.main()方法;
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
4.5.1 关于RuntimeInit.applicationInit{invokeStaticMain}为何会触发ActivityThread.main方法
(1) 在上文Process.start时会传入: entryPoint = "android.app.ActivityThread";
(2) Process.start触发器内部的startViaZygote()方法:
private static ProcessStartResult startViaZygote(final String processClass,
                                  final String niceName,
                                  final int uid, final int gid,
                                  final int[] gids,
                                  int debugFlags, int mountExternal,
                                  int targetSdkVersion,
                                  String seInfo,
                                  String abi,
                                  String instructionSet,
                                  String appDataDir,
                                  String[] extraArgs)
                                  throws ZygoteStartFailedEx {
    synchronized(Process.class) {
        ArrayList<String> argsForZygote = new ArrayList<String>();

        // --runtime-args, --setuid=, --setgid=,
        // and --setgroups= must go first
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
    }
    // 可以看出来此时processClass是以怎样的形式被追加到argsForZygote末尾的;
    argsForZygote.add(processClass);
}
4.6 ActivityThread.main
public static void main(String[] args) {
    Looper.prepareMainLooper();
    ActivityThread thread = new ActivityThread();
    thread.attach(false);
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
    Looper.loop();
}
4.7 ActivityThread.attach
private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        // mgr指向的是AMP;
        final IActivityManager mgr = ActivityManagerNative.getDefault();
        mgr.attachApplication(mAppThread);
    } else {
        ...
    }
}
4.8 ActivityManagerProxy.attachApplication
public void attachApplication(IApplicationThread app) throws RemoteException
{
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IActivityManager.descriptor);
    data.writeStrongBinder(app.asBinder());
    // 同理此时又会触发ActivityManagerService.onTransact
    mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
    reply.readException();
    data.recycle();
    reply.recycle();
}

五、system_server进程

5.1 ActivityManagerService.onTransact
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
    switch (code) {
        case ATTACH_APPLICATION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IApplicationThread app = ApplicationThreadNative.asInterface(
                    data.readStrongBinder());
            if (app != null) {
                // 该方法接下来会依次触发下列调用链
                attachApplication(app);
            }
            return true;
        }
    }
}
@Override
public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
    // thread指向ApplicationThreadProxy
    thread.bindApplication(...);
    // 这里是触发Activity启动的逻辑;这个放在模块七中;
    mStackSupervisor.attachApplicationLocked(app);
}
5.2 ApplicationThreadProxy.bindApplication
@Override
public final void bindApplication(String packageName, ApplicationInfo info,
            List<ProviderInfo> providers, ComponentName testName, ProfilerInfo profilerInfo,
            Bundle testArgs, IInstrumentationWatcher testWatcher,
            IUiAutomationConnection uiAutomationConnection, int debugMode,
            boolean enableBinderTracking, boolean trackAllocation, boolean restrictedBackupMode,
            boolean persistent, Configuration config, CompatibilityInfo compatInfo,
            Map<String, IBinder> services, Bundle coreSettings) throws RemoteException {
    // ...
    // 不深入源码, 按照惯例, 此时触发App进程的ApplicationThread.onTransact()方法的执行;
    mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
}

六、App进程

6.1 ApplicationThread.onTransact
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
    switch (code) {
        case BIND_APPLICATION_TRANSACTION:
        {
            // ...
            bindApplication(packageName, info, providers, testName, profilerInfo, testArgs,
                    testWatcher, uiAutomationConnection, testMode, enableBinderTracking,
                    trackAllocation, restrictedBackupMode, persistent, config, compatInfo, services,
                    coreSettings);
            return true;
        }
    }
}
public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) {
    // ActivityThread内部Handler H接收消息
    sendMessage(H.BIND_APPLICATION, data);
}
6.2 H.handleMessage
 public void handleMessage(Message msg) {
    switch (msg.what) {
        case BIND_APPLICATION:
            AppBindData data = (AppBindData)msg.obj;
            // 最终触发LoadedApk.makeApplication;
            handleBindApplication(data);
            break;
    }
}
6.3 LoadedApk.makeApplication(初始化Application以及调用attachBaseContext与onCreate方法)
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
    Application app = null;
    ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
    app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
    instrumentation.callApplicationOnCreate(app);
}
public class Instrumentation {
    public Application newApplication(ClassLoader cl, String className, Context context) {
        return newApplication(cl.loadClass(className), context);
    }

    static public Application newApplication(Class<?> clazz, Context context) {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }
}
public class Application {
    final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }
}

七、Activity的启动

7.1 ActivityStackSupervisor.attachApplicationLocked(system_server进程)
boolean attachApplicationLocked(ProcessRecord app) {
    if (realStartActivityLocked(hr, app, true, true)) {
        didSomething = true;
    }
}
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) {
    // app.thread指向ApplicationThreadProxy;
    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);
}
7.2 ApplicationThreadProxy.scheduleLaunchActivity(system_server进程)
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) {
    // 根据IPC特点, 最终会触发App进程的ApplicationThread.onTransact方法
    mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
}
7.3 ApplicationThread.onTransact(App进程)
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
    switch (code) {
        case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
        {
            ...
            scheduleLaunchActivity(intent, b, ident, info, curConfig, overrideConfig, compatInfo,
                    referrer, voiceInteractor, procState, state, persistentState, ri, pi,
                    notResumed, isForward, profilerInfo);
            return true;
        }
    }
}

@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) {
    // 终于到了启动Activity的地方, 到此Activity启动流程分析完成;
    sendMessage(H.LAUNCH_ACTIVITY, r);
}

相关文章

网友评论

      本文标题:Binder篇_03Activity启动流程学习

      本文链接:https://www.haomeiwen.com/subject/iirslqtx.html