美文网首页
Activiy启动流程(基于Android 8.0)

Activiy启动流程(基于Android 8.0)

作者: pujyzx | 来源:发表于2019-04-04 13:19 被阅读0次

    启动Activity的过程有两种,一种是从桌面Launch进程启动,另外一种是Activity启动另外一个Activity

    一、前半部分启动分析

    查看Activity$startActivity源码如下:

    1. Activity$startActivity

      @Override
        public void startActivity(Intent intent) {
            this.startActivity(intent, null);
        }
    
        //继续查看
    
        @Override
        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);
            }
        }
    

    2.Activity$startActivityForResult

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
                @Nullable Bundle options) {
            if (mParent == null) {
                Instrumentation.ActivityResult ar =
                    mInstrumentation.execStartActivity(
                        this, mMainThread.getApplicationThread(), mToken, this,
                        intent, requestCode, options);
                if (ar != null) {
                //mMainThread是一个ActivityThread对象,该对象初始化在当前Activity的attach方法中,attach方法在performLaunchActivity()里面调用.
                //attach方法中还创建了PhoneWindow对象,phoneWindow调用setWindowManager创建了WindowMangerImpl,负责View的添加,删除,更新。
                
                    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);
                }
            }
        }
    

    mMainThread.getApplicationThread()返回的是一个ApplicationThread对象,ApplicationThread是ActivityThread的内部类。
    查看ApplicationThread源码如下:

    public final class ActivityThread {
       
       final ApplicationThread mAppThread = new ApplicationThread();
    
       //...code
    
       private class ApplicationThread extends IApplicationThread.Stub {
       
           //...code
       }
    
    }
    

    ApplicationThread继承了IApplicationThread.Stub,说明这里Android使用了AIDL技术实现进程间通信。Stub继承自Binder,ApplicationThread就是一个Binder对象。回到startActivityForResult 调用了Instrumentation$execStartActivity,接着看execStartActivity的代码。

    3.Instrumentation$execStartActivity

    public ActivityResult execStartActivity(
                Context who, IBinder contextThread, IBinder token, Activity 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 != null ? target.mEmbeddedID : null,
                            requestCode, 0, null, options);
                //异常检查,检查Activity是否在Mainifest.xml中声明
                checkStartActivityResult(result, intent);
            } catch (RemoteException e) {
                throw new RuntimeException("Failure from system", e);
            }
            return null;
        }
         /** @hide */
        public static void checkStartActivityResult(int res, Object intent) {
            if (!ActivityManager.isStartResultFatalError(res)) {
                return;
            }
    
            switch (res) {
                case ActivityManager.START_INTENT_NOT_RESOLVED:
                case ActivityManager.START_CLASS_NOT_FOUND:
                    if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                        throw new ActivityNotFoundException(
                                "Unable to find explicit activity class "
                                + ((Intent)intent).getComponent().toShortString()
                                + "; have you declared this activity in your AndroidManifest.xml?");
                    throw new ActivityNotFoundException(
                            "No Activity found to handle " + intent);
                case ActivityManager.START_PERMISSION_DENIED:
                    throw new SecurityException("Not allowed to start activity "
                            + intent);
                case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
                    throw new AndroidRuntimeException(
                            "FORWARD_RESULT_FLAG used while also requesting a result");
                case ActivityManager.START_NOT_ACTIVITY:
                    throw new IllegalArgumentException(
                            "PendingIntent is not an activity");
                case ActivityManager.START_NOT_VOICE_COMPATIBLE:
                    throw new SecurityException(
                            "Starting under voice control not allowed for: " + intent);
                case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
                    throw new IllegalStateException(
                            "Session calling startVoiceActivity does not match active session");
                case ActivityManager.START_VOICE_HIDDEN_SESSION:
                    throw new IllegalStateException(
                            "Cannot start voice activity on a hidden session");
                case ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION:
                    throw new IllegalStateException(
                            "Session calling startAssistantActivity does not match active session");
                case ActivityManager.START_ASSISTANT_HIDDEN_SESSION:
                    throw new IllegalStateException(
                            "Cannot start assistant activity on a hidden session");
                case ActivityManager.START_CANCELED:
                    throw new AndroidRuntimeException("Activity could not be started for "
                            + intent);
                default:
                    throw new AndroidRuntimeException("Unknown error code "
                            + res + " when starting " + intent);
            }
        }
    

    ActivityManager.getService().startActivity(...),就是IActivityManager的代理对象调用了startActivity方法,通过Binder机制,它会使系统服务ActivityManagerService的startActivity方法被调用。因此,启动Activity的操作就交给了系统服务ActivityManagerService来处理了。

    二、启动Activity的交给系统服务ActivityManagerService

        @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,
                    "startActivityAsUser");
        }
    

    最终会调用如下代码:

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                boolean andResume, boolean checkConfig) throws RemoteException {
        //...code
    
        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global and
                        // override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, !andResume,
                        mService.isNextTransitionForward(), profilerInfo);
    
        //...code       
    }
    
    

    app.thread调用scheduleLaunchActivity方法,通过Binder机制,会使ApplicationThread$scheduleLaunchActivity方法被调用。

    三、启动Activity的操作,交给ApplicationThread来处理

    1.ApplicationThread$scheduleLaunchActivity

    查看ApplicationThread$scheduleLaunchActivity方法源码如下:

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

    通过 sendMessage(H.LAUNCH_ACTIVITY, r)和本地UI线程进行通信,查看H$handleMessage源码如下:

    private class H extends Handler {
    
        //...code
        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;
            
        //...code
    
    }
    

    2.ActivityThread$handleLaunchActivity

    查看ActivityThread$handleLaunchActivity源码如下:

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
       //...code
    
       Activity a = performLaunchActivity(r, customIntent);
    
       //...code
    
       if (a != null) {
           //...code
           handleResumeActivity(r.token, false, r.isForward,
                       !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
           //...code
    
       } else {
           // If there was an error, for any reason, tell the activity manager to stop us.
           try {
                ActivityManager.getService()
                       .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                               Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
               } catch (RemoteException ex) {
                   throw ex.rethrowFromSystemServer();
               }
       }
    
    }
    

    performLaunchActivity创建Activity,如果Activity不为空,则调用handleResumeActivity(),执行OnResume回调。

    3.ActivityThread$performLaunchActivity

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
           ActivityInfo aInfo = r.activityInfo;
           if (r.packageInfo == null) {
               r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                       Context.CONTEXT_INCLUDE_CODE);
           }
           //Component 启动Activity的方式:  ComponentName chatActivity =new ComponentName("com.example", "com.example.ui.MainActivity");
           //Intent intent =new Intent(); intent.setComponent(chatActivity); startActivity(intent);
    
    
           //获取要启动的Activity的ComponentName对象:里面包含了包名,类名相关的信息;
           ComponentName component = r.intent.getComponent();
           if (component == null) {
               component = r.intent.resolveActivity(
                   mInitialApplication.getPackageManager());
               r.intent.setComponent(component);
           }
    
           if (r.activityInfo.targetActivity != null) {
               component = new ComponentName(r.activityInfo.packageName,
                       r.activityInfo.targetActivity);
           }
    
           //创建了Activity的上下文环境
           ContextImpl appContext = createBaseContextForActivity(r);
           Activity activity = null;
           
           //...code
           java.lang.ClassLoader cl = appContext.getClassLoader();
           activity = mInstrumentation.newActivity(
                   cl, component.getClassName(), r.intent);
                       
           //创建Application对象
           Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    
               //...code
    
           if (activity != null) {
                   
           //...code
           //调用Activity$attach方法:初始化PhoneWindow,WindowManagerImpl ,context上下文等
                   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);
    
                   //...code
                   //启动Activity:调用Instrumentation$callActivityOnCreate方法;
                   mInstrumentation.callActivityOnCreate(activity, r.state);
    
           //...code
            }
      
           return activity;
    }
    

    r.packageInfo为LoadAPK对象,调用了LoadAPK$makeApplication,查看源码如下:

    public Application makeApplication(boolean forceDefaultAppClass,
                Instrumentation instrumentation) {
            if (mApplication != null) {
                return mApplication;
            }
    
        Application app = null;
    
        java.lang.ClassLoader cl = getClassLoader();
        //...
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        app = mActivityThread.mInstrumentation.newApplication(
                        cl, appClass, appContext);
        
        //...
        mApplication = app;
        //调用此方法会回调Application的onCreate方法
        instrumentation.callApplicationOnCreate(app);
        //...
    
        return app;
    }
    

    创建Application对象跟创建Activity一样,都是通过类加载器ClassLoader来创建实例。如果Application已经存在,那么返回当前的Application,保证单个进程内Application的唯一,创建完Application后,调用Activity.attach方法,初始化PhoneWindow等数据,最后再调用 Instrumentation.callActivityOnCreate启动Activity,这个方法内部又调用了Activity$performCreate方法,最后回调Activity的onCreate方法。

    相关文章

      网友评论

          本文标题:Activiy启动流程(基于Android 8.0)

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