Android框架简介--Activity--Activity启

2022-03-27  本文已影响0人  llm_5243

以Activity A 启动 Activity B,Activity B所在进程未启动为例
大体经过已经几个阶段:

startActivity.png

第一步 Activity A 调用AMS 启动接口

这是一个binder通讯,正常启动Activity的方式,一般我们都会通过以下的方式启动一个新的Activity

startActivity(new Intent(A_Activity.this,B_Activity.class));

这是Activity类的接口,最终会调用到

    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);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
          
        }
    }

这里关键点会调用Instrumentation 的execStartActivity方法。
frameworks/base/core/java/android/app/Instrumentation.java
源码注释大体意思是Instrumentation类会在应用的任何代码执行前被实列化,用来监控系统与应用的交互。可在以应用的AndroidManifest.xml中<instrumentation>标签来注册一个Instrumentation的实现。
基本上在application和activity的所有生命周期调用中,都会先调用instrumentation的相应方法。Instrumentation另一个重要作用是提供Android组件单元测试。这里不做深究。

 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 = ActivityManager.getService()
                .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;
    }

ActivityManager.getService().startActivity 这一步会通过binder的方式调用到AMS的接口

第二步 收集应用信息,pause ActivityA

startActivity --> startActivityAsUser -- > mActivityStarter.startActivityMayWait

这里会调用到类 ActivityStarter

/**
 * Controller for interpreting how and then launching activities.
 *
 * This class collects all the logic for determining how an intent and flags should be turned into
 * an activity and associated task and stack.
 */
class ActivityStarter

从注释上看,我们了解了ActivityStarter的作用是收集所有的逻辑,用来决定如何启动activity, ActivityStarter又通过ActivityStackSupervisor来管理ActivityStack

略过中间环节,会调用到ActivityStack的resumeTopActivityInnerLocked

boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    // ......
    boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
    if (mResumedActivity != null) {
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "resumeTopActivityLocked: Pausing " + mResumedActivity);
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
    // ......
    if (next.attachedToProcess()) {
        try {
        // ......
            transaction.setLifecycleStateRequest(
                    ResumeActivityItem.obtain(next.app.getReportedProcState(),
                            getDisplay().mDisplayContent.isNextTransitionForward()));
            mService.getLifecycleManager().scheduleTransaction(transaction);
        } catch (Exception e) {
            // ......
            mStackSupervisor.startSpecificActivityLocked(next, true, false);
            return true;
        }
        // ......
    } else {
        // Whoops, need to restart this activity!
        if (!next.hasBeenLaunched) {
            next.hasBeenLaunched = true;
        } else {
            if (SHOW_APP_STARTING_PREVIEW) {
                next.showStartingWindow(null /* prev */, false /* newTask */,
                        false /* taskSwich */);
            }
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
        }
        if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }

    return true;
}

此处先通过startPausingLocked流程使mResumedActivity pause。

第三步 通过Zygote创建应用进程

下一步则通过 ActivityStackSupervisor 中的startSpecificActivityLocked方法来执行启动ActivityB流程

    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);


        if (app != null && app.thread != null) {
            try {
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } 

            // 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);
    }

这个函数,先判断ActivityB所在的进程是否启动,如果已经启动则执行realStartActivityLocked, 如果没有则走mService.startProcessLocked流程去启动一个进程. mService为ActivityManagerService

private final void startProcessLocked(ProcessRecord app,) {

       if (entryPoint == null) entryPoint = "android.app.ActivityThread";
       startResult = Process.start(entryPoint,);

       synchronized (mPidsSelfLocked) {
                this.mPidsSelfLocked.put(startResult.pid, app);
                if (isActivityProcess) {
                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                    msg.obj = app;
                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
                }
            }
}

frameworks/base/core/java/android/os/Process.java

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

frameworks/base/core/java/android/os/Process.java

 public final Process.ProcessStartResult start(final String processClass,) {
        try {
            return startViaZygote(processClass, );
        } 
    }

这里 entryPoint = "android.app.ActivityThread" 为启动的java类, 该变量会作为参数给到Process。 Process.start(entryPoint,) 最终会通过socket跟Zygote通讯,Zygote 会去fork一个进程,入口就是entryPoint。

Zygote启动完进程后会返回一个pid,这个pid包含在startResult里面,接着会将pid和app 放入mPidsSelfLocked, 并发送一个延时消息,如果ActivityThread在一定的TIMEOUT(10s)还没向AMS报告,则该消息会被执行,AMS会去清除这个应用的所有信息

第四步 应用进程启动及跟AMS交互

frameworks/base/core/java/android/app/ActivityThread.java

    public static void main(String[] args) {
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        Looper.loop();
    }
 private void attach(boolean system) {
           final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
}

这里的attach就是向AMS注册

下面回到AMS中去执行

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
        //首先根据pid取出 ProcessRecord
        app = mPidsSelfLocked.get(pid);

        //thread为应用端的binder对象,会去通知应用端做一些Application初始化
         thread.bindApplication(processName,...)
         ...
         //处理被挂起的应用组件(activity,service,broadcast),之前应用进程还没被创建
         mStackSupervisor.attachApplicationLocked(app)
         ...
         mServices.attachApplicationLocked()

         sendPendingBroadcastsLocked(app)
         
}
boolean attachApplicationLocked(ProcessRecord app)  {
      final ActivityRecord top = stack.topRunningActivityLocked();
      realStartActivityLocked(activity, app,
}

stack为mFocusStack, 这一部为取出栈顶的Activity,即我们要启动的activity,虽然之前activity没启动,但ams里面栈的信息在启动进程前都已经准备好了。

final boolean realStartActivityLocked() {
    app.thread.scheduleLaunchActivity
}

app为ProcessRecord对象,thread为应用注册到AMS的binder对象. 这里调用了应用的scheduleLaunchActivity,从名字看表示可以加载activity了

第五步 Activity启动

下面就切回到ActivityThread中去执行

public final void scheduleLaunchActivity() {
    ActivityClientRecord r = new ActivityClientRecord();
    sendMessage(H.LAUNCH_ACTIVITY, r);
}

通过发送消息给主线程去处理

 public void handleMessage(Message msg) {
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {

                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                } break;

getPackageInfoNoCheck 会去loadApk加载apk的一些信息,后面启动activity需要调用到,下面会去执行的activity的生命周期

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    Activity a = performLaunchActivity(r, customIntent);
    if (a != null) {
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
            }
}
private Activity performLaunchActivity {
      //创建一个Activity
      activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
       // 获取之前创建的Application
       Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        //创建Context, 并将Context赋值给activity
        ContextImpl appContext = createBaseContextForActivity(r);
       activity.attach(appContext, this, ...)

       //调用到Activity onCreate函数 
       mInstrumentation.callActivityOnCreate(activity, r.state);
       //调用到Activity onStart函数 
       activity.performStart();
}

大体流程可以用下图表示

activity启动.png

参考:
网络课程 --剖析Framework面试 冲击Android高级职位

上一篇下一篇

猜你喜欢

热点阅读