Android四大组件的启动分析与整理(一):Activity的启动过程

Activity的启动过程

Service的启动过程

Broadcast的启动过程

ContentProvider的启动过程

前言

换工作后,一直忙,没时间整理,逼自己一把吧,目标一周整理出来,理顺思路,这里先起个头。
以后得养成一个习惯,先放总结,然后分析:
在这里插入图片描述

  1. Instrumentation:两个作用,一、它是app进程的出口,通过Binder机制调用AMS中的startActivity()方法;二、作为一个外观模式,触发调用activity中的各种生命周期
  2. 到AMS之后,调用重要的一个类ActivityStarter,用来创建activit启动的必要参数activityRecord、taskRecord(根据设定的启动模式来创建)并添加到activityStack中

Activity的启动分两种,一种是根Activity的启动,另一种是普通Activity的启动,根Activity的启动,从LauncherActivity开始,启动方式跟我们平时的startActivity是基本一样的。

android.app.Activity.class

public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
       。。。。。。。。。。。
       //设置flag为new task
       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
       。。。。。。。。。。。
            if (Utilities.ATLEAST_MARSHMALLOW
                    && (item instanceof ShortcutInfo)
                    && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
                     || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
                    && !((ShortcutInfo) item).isPromise()) {
                // Shortcuts need some special checks due to legacy reasons.
                startShortcutIntentSafely(intent, optsBundle, item);
            } else if (user == null || user.equals(Process.myUserHandle())) {
                // Could be launching some bookkeeping activity
                //通过startActivity开启
                startActivity(intent, optsBundle);
            } 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;
    }

当点击桌面的图标的时候,调用startActivitySafely(),然后先设置它的flag是new task,然后调用Activity的startActivity()方法,然后调用继续调用startActivityForResult(intent, -1, options);-1表示launch不需要知道启动结果,

	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);
        。。。。。。。。。。。。
        } else {
        。。。。。。。。。。。。
        }
    }
    

因为根Activity,mParent肯定为null,Activity最终都会通过Instrumentation工具类去执行,这里就调用了execStartActivity()方法。

这里就到了android.app.Instrumentation.class中

	public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, String target,
        Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        。。。。。。。。。。
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target, requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

instrumentation中通过调用ActivityManager.getService()方法,得到AMS,然后调用AMS中的startActivity方法继续执行。

    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

这里需要注意一下,在Android8.0以前,都是通过ActivityManagerNative.getDefalt()方法,然后通过IActivtyManager am= asinterface (b) ; 去获取AMS的代理类ActivityManagerProxy对象的。在asinterface 中直接new ActivityManagerProxy(b)并返回,8.0之后通过通过IActivityTaskManager.Stub.asInterface(b)去获得,典型的AIDL写法,AMS中继承了IActivityManager.Stub。

com.android.server.am.ActivityManagerService#startActivity(IApplicationThread, String, Intent, String, IBinder, String, int, int, ProfilerInfo, Bundle)

@Override
    public final int startActivity(.....) {
        return startActivityAsUser(.....UserHandle.getCallingUserId());
    }
    public final int startActivityAsUser(.....) {
    enforceNotIsolatedCaller("startActivity");1)
    userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),2)
    userId, false, ALLOW_FULL_ONLY, "startActivity", null);
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
    profilerInfo, null, null, bOptions, false, userId, null, null,
    "startActivityAsUser");
    }

(1)处判断调用者的进程是否被隔离,如果是就抛出SecurityException异常。
(2)处检查调用者是否有权限,如果没有也会抛出SecurityException异常。
然后继续调用ActivityStarter中的startActivityMayWait()方法,ActivityStarter是Activity的一个控制类,主要将flag和intent转为Activity,然后将Activity和task以及stack关联起来。

int startActivityLocked(...., String reason) {
        if (TextUtils.isEmpty(reason)) {1throw new IllegalArgumentException("Need to specify a reason.");
        }
        mLastStartReason = reason;
        mLastStartActivityTimeMs = System.currentTimeMillis();
        mLastStartActivityRecord[0] = null;
        mLastStartActivityResult = startActivity(....);
        if (outActivity != null) {
            outActivity[0] = mLastStartActivityRecord[0];
        }
        return mLastStartActivityResult;
    }

startActivityMayWait()方法很长,其中调用了startActivityLocked方法,(1)处就是之前传入的“startActivityAsUser”参数,用来说明调用原因,如果没有原因,抛出IllegalArgument异常,然后继续调用startActivity方法。

private int startActivity(IApplicationThread caller,.....ActivityRecord[] outActivity,.....) {
      int err = ActivityManager.START_SUCCESS;
      final Bundle verificationBundle
              = options != null ? options.popAppVerificationBundle() : null;
      ProcessRecord callerApp = null;
      if (caller != null) {1//获取Launcher进程
          callerApp = mService.getRecordForAppLocked(caller);//2
          if (callerApp != null) {
            //获取Launcher进程的pid和uid并赋值
              callingPid = callerApp.pid;
              callingUid = callerApp.info.uid;
          } else {
              Slog.w(TAG,.....);
              err = ActivityManager.START_PERMISSION_DENIED;
          }
      }
      ...
      //创建即将要启动的Activity的描述类ActivityRecord
      ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
              callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
              resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
              mSupervisor, container, options, sourceRecord);2if (outActivity != null) {
          outActivity[0] = r;3}
      ...
          doPendingActivityLaunchesLocked(false);
          return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
              options, inTask, outActivity);//4
  }

这里首先在(1)处通过AMS的getRecordForAppLocked方法获取请求进程对象callerApp ,因为是从launcher启动,所以这里是launcher所在的进程,他是一个ProcessRecord对象,然后拿到pid和uid。
(2)处创建Activity信息,这样ProcessRecord和ActivityRecord就齐全了。继续startActivity;

    private int startActivityUnchecked(....) {
        ........
        int result = START_SUCCESS;
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);—————(1} else if (mSourceRecord != null) {
            result = setTaskFromSourceRecord();
        } else if (mInTask != null) {
            result = setTaskFromInTask();
        } else {
        .........
            setTaskToCurrentTopOrCreateNewTask();
        }
        ........
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                mWindowManager.executeAppTransition();
            } else {
                if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);————(2}
        } else {
            mTargetStack.addRecentActivityLocked(mStartActivity);
        }
        .............
        return START_SUCCESS;
    }

(1)处通过setTaskFromReuseOrCreateNewTask()方法,创建TaskRecorder,这样一来,ProcessRecorder、ActivityRecorder以及TaskRecorder都齐全了,
(2)处调用resumeFocusedStackTopActivityLocked方法

    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);
        } else if (r.state == RESUMED) {
            mFocusedStack.executeAppTransition(targetOptions);
        }
        return false;
    }
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            return false;
        }
        boolean result = false;
        try {
            mStackSupervisor.inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        mStackSupervisor.checkReadyForSleepLocked();
        return result;
    }

这里因为我们启动的是根Activity,那么topActivity肯定是为没有在running状态的,走的resumeTopActivityUncheckedLocked方法,然后执行resumeTopActivityInnerLocked方法。

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    ........
        ActivityStack lastStack = mStackSupervisor.getLastStack();
        if (next.app != null && next.app.thread != null) {
            final boolean lastActivityTranslucent = lastStack != null
                    && (!lastStack.mFullscreen
                    || (lastStack.mLastPausedActivity != null
                    && !lastStack.mLastPausedActivity.fullscreen));
                    ..........
        } else {
        ..........
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }

这里代码很多,最终执行的是ActivityStackSupervisor类中的startSpecificActivityLocked方法。

    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        r.getStack().setLaunchTime(r);
        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);(1)
                return;
            } catch (RemoteException e) {
            }
        }
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);(2)
    }

这里先获取启动进程ProcessRecord 然后调用realStartActivityLocked()方法;
如果ProcessRecorder进程为null那么就通过AMS的startProcessLocked去执行Process.start创建。

    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,
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);
        ..........
        return true;
    }

其中app.thread其实就是ProcessRecorder的IApplicationManager,也就是ActivityThread的内部类ApplicationThread。
Activity启动过程其实就目标应用程序进程启动Activity的过程,这里的app就代表目标应用程序进程,那ApplicationThread继承了IApplicationThread.Stub就是目标应用程序与AMS进行binder通信的桥梁。
最后通知ApplicationThread调用scheduleLaunchActivity去启动Activity;

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) {
            updateProcessState(procState, false);
            ActivityClientRecord r = new ActivityClientRecord();
            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.persistentState = persistentState;
            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;
            r.startsNotResumed = notResumed;
            r.isForward = isForward;
            r.profilerInfo = profilerInfo;
            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

这里就是设置一堆属性,然后通过Activity的内部类H,其实就是handler类,发送LAUNCH_ACTIVITY消息,去执行

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;
----------------handleLaunchActivity------------------
Activity a = performLaunchActivity(r, customIntent);

然后调用handleLaunchActivity,然后继续调用performLaunchActivity,要执行一个Activity首先需要两个必备因素,一个是Context上下文,一个是Application。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
.......................
        ContextImpl appContext = createBaseContextForActivity(r);1Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);2.......................
        } catch (Exception e) {
        .......................
        }
        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);3if (activity != null) {
.......................
                appContext.setOuterContext(activity);
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);4.......................
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);5} else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
.......................
        return activity;
    }

(1)处就是通过new ContextImpl的方式,创建Actviity的上下文。
(2)处就是通过反射的方式,创建Actviity类。
(3)处通过反射的方式,创建Application类,并把ContextImpl(这个上下文跟Activity的不一样,上面那个多了token和classloader)上下文attach到父类ContextWrapper中去,也就是mBase。
(4)有了ContextImpl和Application,然后将Actviity做attach操作,就是将ContextImpl给父类ContextWrapper中的mBase,同时创建PhoneWindow。
(5)处就是通过Instrumentation去调用oncreate方法

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值