App启动流程分析(上)

本文详细剖析了Android App从启动图标被点击开始,到Activity实际运行的整个过程,包括远程调用AMS、Binder通信、AMS内部处理、Zygote进程的fork与初始化,直至Application的创建与onCreate调用。通过对每个关键步骤的分析,帮助读者理解App启动的内在机制。
摘要由CSDN通过智能技术生成

App启动流程分析

一.概述流程

  1. 在LAUNCH界面,点击一个app的图标之后,会调用startActivity来启动对应的Activity。

  2. 通过Binder远程通知AMS启动新的Activity。

  3. AMS进行一系列的权限判断,创建ActivityRecord记录信息,Activity栈处理….等等一系列处理,最后会调用到startSpecificActivityLocked方法中。
  4. startSpecificActivityLocked方法中会进行判断,在进程没有启动的情况下,会调用startProcessLocked=>startProcessLocked=>Process.start()来启动一个进程。
  5. Process.start()是一个静态方法,他作为客户端会通过sockt与zygote进行通讯,Zygote作为服务端。Zygote通过JNI调用native方法fork一个它的子进程,并返回进程的pid。
  6. 调用zygoteConnection的handleChildProc方法。关闭socoket,进行一些进程的设置,默认未捕捉异常的处理方法、时区的设置、重置log的配置,binder线程池和线程创建….
  7. 通过反射来调用到ActivityThread的main方法,main方法中创建主线程Looper、并调用attach方法。通过Binder通讯调用AMS的attachApplicationLocked()方法,启动主线程Looper循环。
  8. 跨进程调用ApplicationThread的bindApplication方法,通过Handler发送消息调用到ActivityThread的handleBindApplication方法,在这个方法中会完成创建Context的实现类ContextImpl对象、初始化Intrumentation对象、创建Application对象、装载Provider、调用Application的onCreate方法。
  9. 调用到realStartActivityLocked,然后跨进程调用到applicationThread的scheduleLaunchActivity方法,scheduleLaunchActivity就会正真创建Activity。

二.具体流程分析

一 . 远程调用AMS中StartActivity

1.1 StartActivity

在Android中,当我们启动一个新的Activity或者service时,都是直接在Activity中调用StartActivity或者startService方法。这个方法最终会调用到startActivityForResult

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
          //调用Instrumentation中的execStartActivity方法
            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());
            }
          //requestCode为-1
            if (requestCode >= 0) {
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);

        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

其中:mMainThread的数据类型是ActivityThread,其中mMainThread.getApplicationThread()方法得到ApplicationThread;

1.2 execStartActivity
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    if (am.match(who, null, intent)) {
                        am.mHits++;
                      //如果阻塞,直接return
                        if (am.isBlocking()) {
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        try {
            intent.setAllowFds(false);
          //获得ActivityManagerProxy对象,调用startActivity
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        null, 0, token, target != null ? target.mEmbeddedID : null,
                        requestCode, false, false, null, null, false);
          //检查Activity是否启动成功
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
        }
        return null;
    }
}

其中ActivityManagerNative.getDefault()会获得ActivityManagerService的本地代理对象ActivityManagerProxy, 调用ActivityManagerProxy.startActivity会通过Binder跨进程调用AMS中的startActivity方法;

二 Binder远程调用

2.1 ActivityManagerNative.getDefault().startActivity
            public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case START_ACTIVITY_TRANSACTION:
        {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            Uri[] grantedUriPermissions = data.createTypedArray(Uri.CREATOR);
            int grantedMode = data.readInt();
            IBinder resultTo = data.readStrongBinder();
            String resultWho = data.readString();    
            int requestCode = data.readInt();
            boolean onlyIfNeeded = data.readInt() != 0;
            boolean debug = data.readInt() != 0;
            String profileFile = data.readString();
            ParcelFileDescriptor profileFd = data.readInt() != 0
                    ? data.readFileDescriptor() : null;
            boolean autoStopProfiler = data.readInt() != 0;
            //远程调用AMS中的startActivity
            int result = startActivity(app, intent, resolvedType,
                    grantedUriPermissions, grantedMode, resultTo, resultWho,
                    requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler);
            reply.writeNoException();
            reply.writeInt(result);
            return true;
        }

三 AMS中具体启动流程

3.1 AMS.startActivity()
public final int startActivity(IApplicationThread caller,
            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
            int grantedMode, IBinder resultTo,
            String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
            String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {

  //直接调用了ActivityStack中的startActivityMayWait
        return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
                grantedUriPermissions, grantedMode, resultTo, resultWho,
                requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
                null, null);
    }
3.2 ActivityStack.startActivityMayWait()

直接调用了ActivityStack中的方法

 final int startActivityMayWait(IApplicationThread caller, int callingUid,
            Intent intent, String resolvedType, Uri[] grantedUriPermissions,
            int grantedMode, IBinder resultTo,
            String resultWho, int requestCode, boolean onlyIfNeeded,
            boolean debug, String profileFile, ParcelFileDescriptor profileFd,
            boolean autoStopProfiler, WaitResult outResult, Configuration config) {
        ...
        intent = new Intent(intent);

        // 根据传入的Intent收集要启动的目标Activity的信息
        ActivityInfo aInfo = resolveActivity(intent, resolvedType, debug,
                profileFile, profileFd, autoStopProfiler);

        ...
        ActivityContainer container = (ActivityContainer)iContainer;
    synchronized (mService) {
      //见3.3小结
            int res = startActivityLocked(caller, intent, resolvedType,
                    grantedUriPermissions, grantedMode, aInfo,
                    resultTo, resultWho, requestCode, callingPid, callingUid,
                    onlyIfNeeded, componentSpecified, null);

          ...

            return res;
        }
    }
3.3 ActivityStack.startActivityLocked()
final int startActivityLocked(IApplicationThread caller,
            Intent intent, String resolvedType,
            Uri[] grantedUriPermissions,
            int grantedMode, ActivityInfo aInfo, IBinder resultTo,
            String resultWho, int requestCode,
            int callingPid, int callingUid, boolean onlyIfNeeded,
            boolean componentSpecified, ActivityRecord[] outActivity) {

        int err = START_SUCCESS;
        //调用者进程记录对象
        ProcessRecord callerApp = null;
        //判断调用者本身进程的存在,否则记录START_PERMISSION_DENIED,并在后面return
        if (caller != null) {
            callerApp = mService.getRecordForAppLocked(caller);
            if (callerApp != null) {
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } else {
                Slog.w(TAG, "Unable to find app for caller " + caller
                      + " (pid=" + callingPid + ") when starting: "
                      + intent.toString());
                err = START_PERMISSION_DENIED;
            }
        }

        if (err == START_SUCCESS) {
            Slog.i(TAG, "START {" + intent.toShortString(true, true, true) + "} from pid "
                    + (callerApp != null ? callerApp.pid : callingPid));
        }
    //调用者Activity的Activity信息记录对象
        ActivityRecord sourceRecord = null;
   //要启动的Activity的Activity信息记录对象
        ActivityRecord resultRecord = null;
        if (resultTo != null) {
            int index = indexOfTokenLocked(resultTo);
            if (DEBUG_RESULTS) Slog.v(
                TAG, "Will send result to " + resultTo + " (index " + index + ")");
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值