美文网首页
Android Activity加载流程

Android Activity加载流程

作者: 昊空_6f4f | 来源:发表于2020-09-01 14:12 被阅读0次

    概述

    本文主要分享Activity的启动流程,主要分析Application与Activity分别是如何被加载的,下面我们就通过阅读源码分析

    Application的加载过程

    这里需要从应用入口ActivityThread开始分析,追溯到main方法,找到如下关键代码:

    public static void main(String[] args) {
        ...   
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);
        ...
    }
    

    追溯到ActivityThread中的attach方法,找到如下关键代码:

     private void attach(boolean system, long startSeq) {
        ...
        final IActivityManager mgr = ActivityManager.getService();
        try {
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        ...
    }
    
    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;
            }
        };
    

    由上述代码可知attach方法中进行了跨进程调用,而IActivityManager是系统进程在本地的代理,而对应的系统进程为ActivityManagerService,追溯attachApplication方法:

     public final void attachApplication(IApplicationThread thread, long startSeq) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }
    

    attachApplication方法又调用了attachApplicationLocked方法,注意方法中以下两个关键点:

    private final boolean attachApplicationLocked(IApplicationThread thread,
                int pid, int callingUid, long startSeq) {
           ...       
                
          //关键点一:Application的初始化
           thread.bindApplication(processName, appInfo, providers,
                    app.instr.mClass,
                    profilerInfo, app.instr.mArguments,
                    app.instr.mWatcher,
                    app.instr.mUiAutomationConnection, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(getGlobalConfiguration()), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked(),
                    buildSerial, isAutofillCompatEnabled);
                        
             //关键点二:Activity的初始化
             if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }           
       ...           
    }
    

    这里先分析关键点一,由于IApplicationThread在ActivityThread中实现,所以回归到ActivityThread类,分析bindApplication方法:

     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 services, Bundle coreSettings,
                    String buildSerial, boolean autofillCompatibilityEnabled) {
                ...  
                AppBindData data = new AppBindData();
                data.processName = processName;
                data.appInfo = appInfo;
                data.providers = providers;
                data.instrumentationName = instrumentationName;
                data.instrumentationArgs = instrumentationArgs;
                data.instrumentationWatcher = instrumentationWatcher;
                data.instrumentationUiAutomationConnection = instrumentationUiConnection;
                data.debugMode = debugMode;
                data.enableBinderTracking = enableBinderTracking;
                data.trackAllocation = trackAllocation;
                data.restrictedBackupMode = isRestrictedBackupMode;
                data.persistent = persistent;
                data.config = config;
                data.compatInfo = compatInfo;
                data.initProfilerInfo = profilerInfo;
                data.buildSerial = buildSerial;
                data.autofillCompatibilityEnabled = autofillCompatibilityEnabled;
                //关键点:通过处理HandlerH.BIND_APPLICATION类型消息  
                sendMessage(H.BIND_APPLICATION, data);
            }
    

    有源码可知,bindApplication通过Handler发生Application绑定消息并进行处理,处理的方法为handleBindApplication,关键代码如下:

     private void handleBindApplication(AppBindData data) {
        ...
         try {
            mInstrumentation.onCreate(data.instrumentationArgs);
        }catch (Exception e) {
            throw new RuntimeException(
                "Exception thrown in onCreate() of "
                + data.instrumentationName + ": " + e.toString(), e);
        }
        try {
            mInstrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
            if (!mInstrumentation.onException(app, e)) {
                throw new RuntimeException(
                  "Unable to create application " + app.getClass().getName()
                  + ": " + e.toString(), e);
            }
        }
        ...
     }
    
    public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }
    

    由源码可知Application的初始化是通过调用Instrumentation类中的callApplicationOnCreate方法进而调用了app.onCreate()完成初始化工作,到这里Application的加载过程就分析完了

    Activity的加载过程

    这里紧接着上面attachApplicationLocked方法中的关键点二继续分析,进入ActivityStackSupervisor类的attachApplicationLocked方法:

     boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
     ...
       for (int i = 0; i < size; i++) {
            final ActivityRecord activity = mTmpActivityList.get(i);
            if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                    && processName.equals(activity.processName)) {
                try {
                    if (realStartActivityLocked(activity, app,
                            top == activity /* andResume */, true /* checkConfig */)) {
                        didSomething = true;
                    }
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception in new application when starting activity "
                            + top.intent.getComponent().flattenToShortString(), e);
                    throw e;
                }
            }
        }
      }
     ...
     }
    

    attachApplicationLocked方法又调用了realStartActivityLocked方法,关键代码如下:

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                boolean andResume, boolean checkConfig) throws RemoteException {
                
     ...
     final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                r.appToken);
        clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                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, mService.isNextTransitionForward(),
                profilerInfo));
    
        // Set desired final state.
        final ActivityLifecycleItem lifecycleItem;
        if (andResume) {
            lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
        } else {
            lifecycleItem = PauseActivityItem.obtain();
        }
        clientTransaction.setLifecycleStateRequest(lifecycleItem);
    
        // Schedule transaction.
        mService.getLifecycleManager().scheduleTransaction(clientTransaction);
         ...
     }
    

    追溯到ClientLifecycleManager类中的scheduleTransaction方法:

    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }
    }
    

    继续追溯到ClientTransaction类中的schedule方法:

    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }
    

    由源码可知,chedule()又调用了IApplicationThread的scheduleTransaction方法,这里回到ActivityThread继续分析:

    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
    

    由上述源码可知,方法内发送了EXECUTE_TRANSACTION类型消息,而对于的处理是在TransactionExecutor类中的execute方法:

     public void execute(ClientTransaction transaction) {
         
            executeCallbacks(transaction);
    
            executeLifecycleState(transaction);
     }
    

    execute方法中分别调用了executeCallbacks和executeLifecycleState,这里先分析executeCallbacks方法:

    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            log("Resolving callback: " + item);
            final int postExecutionState = item.getPostExecutionState();
            final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                    item.getPostExecutionState());
            if (closestPreExecutionState != UNDEFINED) {
                cycleToPath(r, closestPreExecutionState);
            }
    
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            ...      
        }
    }
    

    方法的内部实现是遍历List<ClientTransactionItem>中的元素并逐个执行execute方法,而通过上面分析可知getCallbacks()中添加的元素为ActivityLifecycleItem,进入exexute方法:

     public void execute(ClientTransactionHandler client, IBinder token,
                PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
    

    通过方法实现可知,方法内部调用了IApplicationThread的handleLaunchActivity方法,这里再次回到ActivityThread进行分析:

    public Activity handleLaunchActivity(ActivityClientRecord r,
                PendingTransactionActions pendingActions, Intent customIntent) {
                    
        final Activity a = performLaunchActivity(r, customIntent);
         return a;
    }
    

    进入performLaunchActivity方法,阅读以下关键代码:

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        Activity activity = null;
            try {
                java.lang.ClassLoader cl = appContext.getClassLoader();
                activity = mInstrumentation.newActivity(
                        cl, component.getClassName(), r.intent);
                StrictMode.incrementExpectedActivityCount(activity.getClass());
                r.intent.setExtrasClassLoader(cl);
                r.intent.prepareToEnterProcess();
                if (r.state != null) {
                    r.state.setClassLoader(cl);
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(activity, e)) {
                    throw new RuntimeException(
                        "Unable to instantiate activity " + component
                        + ": " + e.toString(), e);
                }
            }
            
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            
             return activity;
    }
    
    public void callActivityOnCreate(Activity activity, Bundle icicle,
                PersistableBundle persistentState) {
            prePerformCreate(activity);
            activity.performCreate(icicle, persistentState);
            postPerformCreate(activity);
        }
    
     final void performCreate(Bundle icicle, PersistableBundle persistentState) {
            mCanEnterPictureInPicture = true;
            restoreHasCurrentPermissionRequest(icicle);
            if (persistentState != null) {
                onCreate(icicle, persistentState);
            } else {
                onCreate(icicle);
            }
            writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
            mActivityTransitionState.readState(icicle);
    
            mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
                    com.android.internal.R.styleable.Window_windowNoDisplay, false);
            mFragments.dispatchActivityCreated();
            mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
        }
    

    通过上面的关键代码可知,Activity是通过反射进行创建的,创建完成后再通过Instrumentation类调用自身的onCreate方法完成初始化,到这里Activity的加载流程就分析完了,通过分析我们可以看到这个过程中涉及到的类非常多,但是阅读源码本身就是一件繁琐的事,只要抓住主干,一步步去分析,就会慢慢明白了。

    相关文章

      网友评论

          本文标题:Android Activity加载流程

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