activity 生命周期_Activity的创建,和生命周期的调用

前言

从第一天接触Android开发开始,大家都知道Activity是Android中最最最重要的一个组件。既然很重要,很多在Android开发岗位工作几年了,都对Activity讲不出个所以然出来。比如:

1.Activity的创建
2.Activity生命周期函数的调用
既然这么重要,这么多问题困扰小伙伴们,希望通过本章的学习,帮助小伙伴们对Activity有个全新的认识。

众所周知,java程序想要开启需要依赖于main方法,也就是程序入口(主线程)进入。熟悉的小伙伴可能都知道在Android当中存在一个叫做ActivityThread的类,这个类代表的是Android当中的主线程,而在这个类当中会有一个比较熟悉的main方法,Android在打开app时首先调用的是ActivityThread的main方法,这也就是一个app进程的启动点。

##ActivityThreadpublic static void main(String[] args) {        ...        Looper.prepareMainLooper();        long startSeq = 0;        if (args != null) {            for (int i = args.length - 1; i >= 0; --i) {                if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {                    startSeq = Long.parseLong(                            args[i].substring(PROC_START_SEQ_IDENT.length()));                }            }        }        ActivityThread thread = new ActivityThread();  //1        thread.attach(false, startSeq); //2        ...        Looper.loop();        throw new RuntimeException("Main thread loop unexpectedly exited");}

在main方法的注释1处,创建了ActivityThread,接着在注释2处,调用了attach方法,意为连接,具体连接什么,我们接着往下分析。

##ActivityThreadprivate void attach(boolean system, long startSeq) {        ...        if (!system) {            ...            final IActivityManager mgr = ActivityManager.getService();  //1            try {                mgr.attachApplication(mAppThread, startSeq);  //2            } catch (RemoteException ex) {                throw ex.rethrowFromSystemServer();            }            ...        } else {            ...        }        ...}

attach方法,在注释1处,通过AIDL,得到AMS的本地代理对象IActivityManager ,作用应用进程请求系统进程的接口,实现跟AMS服务跨进程间通信。这里设计到AIDL的用法,和AMS相关的基础知识,这部分内容不在本章节探讨。接着看注释2,使用IActivityManager 对象调用了attachApplication方法,主要是为了连接Application。Application这个类小伙伴们肯定是不陌生的,一般会在这个类中去初始化一些需要在Activity启动之前初始化的资源,或是配置一些整个应用需要用到的东西,让真个App(任何类中)都能访问到。那么这里跟AMS进行连接,主要让当前App跟Android系统绑定起来,方便系统管理当前App。

##ActivityManagerServicepublic final void attachApplication(IApplicationThread thread, long startSeq) {        synchronized (this) {            //获取pid            int callingPid = Binder.getCallingPid();  //1            //获取uid            final int callingUid = Binder.getCallingUid();  //2            final long origId = Binder.clearCallingIdentity();            //连接Application            attachApplicationLocked(thread, callingPid, callingUid, startSeq);  //3            Binder.restoreCallingIdentity(origId);        }}

attachApplication是AMS中的一个方法,注释1和2分别获取到pid和uid(由系统创建,并分配,并且是处以没有进程使用)。这里小伙伴们可以猜想一下,获取到pid和uid肯定是把它分配到当前进程。在注释3,可以看到pid和uid传入到了attachApplicationLocked这个方法中。

##ActivityManagerServiceprivate final boolean attachApplicationLocked(IApplicationThread thread,                                                  int pid, int callingUid, long startSeq) {        ProcessRecord app;  //1        long startTime = SystemClock.uptimeMillis();        if (pid != MY_PID && pid >= 0) {            synchronized (mPidsSelfLocked) {                app = mPidsSelfLocked.get(pid);  //2            }        }         ...        if (app.instr != null) {  //当前进程是否正在活动           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);   //3        } else {            //Application 绑定到当前线程            thread.bindApplication(processName, appInfo, providers, null, profilerInfo,                    null, null, null, testMode, mBinderTransactionTrackingEnabled,                    enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,                    new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated),                    mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, isAutofillCompatEnabled);  //4        }        ...        //检测最可见的Activity是否在运行进程中等待,如果再则创建Activity        if (mStackSupervisor.attachApplicationLocked(app)) {  //5            didSomething = true;        }        ...}

attachApplicationLocked方法中,注释1处的ProcessRecord是个进程记录类,小伙伴们可以把这个类理解成为一个javabean,用来保存当前进程先关的一些信息(如pid、uip、ApplicationInfo等),在注释2中,根据pid获取到了这个类。注释3和注释4都是为了绑定Application,调用的是IApplicationThread 中的bindApplication方法,而IApplicationThread 它是一个AIDL接口,作用是系统进程请求应用进程的接口。而它的实现类是在ActivityThread中的一个内部类ApplicationTread继承了IApplicationThread.Stub。注释5是开始创建Activity。这里我们分开来探讨绑定Application和创建Activity。

绑定Application

##ActivityThread.ApplicationThreadpublic final void bindApplication(String processName...boolean autofillCompatibilityEnabled) {        ...        setCoreSettings(coreSettings);        AppBindData data = new AppBindData();        data.processName = processName;  //当前进程名字        data.appInfo = appInfo;     //app信息        data.providers = providers; //providers        ...        //最后使用Handler发送消息,并携带AppBindData数据        sendMessage(H.BIND_APPLICATION, data);}

在ActivityThread.ApplicationTread类中,bindApplication方法携带了一系列参数,把这些数据封装成了一个AppBindData 对象,最后使用Handler发送消息,并携带AppBindData数据。H是ActivityThread中的内部类,是Handler的子类。

##ActivityThread.Hpublic void handleMessage(Message msg) {        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));        switch (msg.what) {            case BIND_APPLICATION:                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");                AppBindData data = (AppBindData) msg.obj;                handleBindApplication(data);                  Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                break;            ...        }        ...}

handleMessage方法是H中的方法,主要是用来处理消息。

##ActivityThread private void handleBindApplication(AppBindData data) {        ...        final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);  //1        ...        Application app;        ...        //创建Application        app = data.info.makeApplication(data.restrictedBackupMode, null);  //2        ...        //调用Application中的onCreate方法        mInstrumentation.callApplicationOnCreate(app);  //3        ...}##Instrumentationpublic void callApplicationOnCreate(Application app) {        app.onCreate();}

handleBindApplication方法中,注释1,获取Application的上下文,也就是getApplicationContext()获取到的ContextImpl ,ContextImpl 是Context的子类。注释2,通过类加载器,和反射创建出Application。注释3,接着可以看到Application的onCreate方法的调用。

小结,链接Application,可以理解为三个步骤,第一个步骤获取pid和uid,第二步通过IApplicationThread请求当前应用进程,第三步创建Application。

##ActivityStackSupervisorboolean attachApplicationLocked(ProcessRecord app) throws RemoteException {        ...        if (realStartActivityLocked(activity, app,                top == activity /* andResume */, true /* checkConfig */)) {            didSomething = true;        }        ...}

经过一系列的检测或判断后,会realStartActivityLocked方法,真正的开始Activity的解锁(创建)。

##ActivityStackSupervisorfinal boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,                                          boolean andResume, boolean checkConfig) throws RemoteException {        ...        // 创建启动Activity        final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,                r.appToken);        clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),                System.identityHashCode(r), r.info,                mergedConfiguration.getGlobalConfiguration(),                mergedConfiguration.getOverrideConfiguration(), r.compat,                r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,                r.persistentState, results, newIntents, mService.isNextTransitionForward(),                profilerInfo));  //添加LaunchActivityItem的回调        // Set desired final state.        final ActivityLifecycleItem lifecycleItem;        if (andResume) {            lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());        } else {            lifecycleItem = PauseActivityItem.obtain();        }        clientTransaction.setLifecycleStateRequest(lifecycleItem);        // 通过生命周期管理对象ClientLifecycleManager,来管理Activity的生命周期状态        mService.getLifecycleManager().scheduleTransaction(clientTransaction);        ...        return true;}

此处,添加LaunchActivityItem。再后续的真正开始创建Activity时会用到。

##ClientLifecycleManagervoid scheduleTransaction(ClientTransaction transaction) throws RemoteException {        final IApplicationThread client = transaction.getClient();        //ClientTransaction是个javabean 实现了Parcelable 序列化。        //schedule()方法内部,会回调到ActivityThread.ApplicationThread的scheduleTransaction()方法        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();        }}

接着会走到

##ActivityThread.ApplicationTreadpublic void scheduleTransaction(ClientTransaction transaction) throws RemoteException {        //ActivityThread.this 指的是父类ClientTransactionHandler        ActivityThread.this.scheduleTransaction(transaction);}##ClientTransactionHandlervoid scheduleTransaction(ClientTransaction transaction) {        transaction.preExecute(this);        //发送Handler消息        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);}

在handleMessage方法中处理的EXECUTE_TRANSACTION这条消息。

##ActivityThread.Hpublic void handleMessage(Message msg) {        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));        switch (msg.what) {            ...            case EXECUTE_TRANSACTION:                final ClientTransaction transaction = (ClientTransaction) msg.obj;                //开始执行                mTransactionExecutor.execute(transaction);                if (isSystem()) {                    // Client transactions inside system process are recycled on the client side                    // instead of ClientLifecycleManager to avoid being cleared before this                    // message is handled.                    transaction.recycle();                }                // TODO(lifecycler): Recycle locally scheduled transactions.                break;                ...        }        ...}

接着看execute方法。

##TransactionExecutorpublic void execute(ClientTransaction transaction) {        final IBinder token = transaction.getActivityToken();        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);        executeCallbacks(transaction);  //1        executeLifecycleState(transaction);  //5        mPendingActions.clear();        log("End resolving transaction");}##TransactionExecutorpublic void executeCallbacks(ClientTransaction transaction) {        final List callbacks = transaction.getCallbacks();  //2        ...        for (int i = 0; i < size; ++i) {            final ClientTransactionItem item = callbacks.get(i);  //3            ...            item.execute(mTransactionHandler, token, mPendingActions);  //4            ...        }}

executeCallbacks方法,注释1执行回调。注释2获取到ClientTransaction中的ClientTransactionItem集合。注释3处理回调,这里获取到的ClientTransactionItem是LaunchActivityItem。注释4调用LaunchActivityItem中的execute方法。注释5是执行生命周期状态的改变,这里没有给小伙伴们贴出代码,感兴趣的小伙伴去看看。举个例子,比如Activity首次创建,默认的生命周期状态是ON_CREATE,再进行完onCreate方法调用结束后,生命周期状态值会往后移,也就是状态改变成ON_START,onStart方法调用结束,状态改变成ON_RESUME。

##LaunchActivityItempublic void execute(ClientTransactionHandler client, IBinder token,                        PendingTransactionActions pendingActions) {        ...        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);  //1        ...}

execute方法中,ClientTransactionHandler是个抽象类,他的子类是ActivityThread。接着调用到的是
ActivityThread中的handleLaunchActivity方法。

##ActivityThreadpublic Activity handleLaunchActivity(ActivityClientRecord r,                                         PendingTransactionActions pendingActions, Intent customIntent) {        ...        //开始执行        final Activity a = performLaunchActivity(r, customIntent);   //1        ...        return a;}

注释1,开始执行启动Activity的创建。

##ActivityThreadprivate Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {        ActivityInfo aInfo = r.activityInfo;   //1        ...        ContextImpl appContext = createBaseContextForActivity(r);   //2        Activity activity = null;        try {            java.lang.ClassLoader cl = appContext.getClassLoader();   //3            activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);  //4           ...        } catch (Exception e) {           ...        }        ...        //调用Activity的OnCreate()方法        if (r.isPersistable()) {            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);   //5        } else {            mInstrumentation.callActivityOnCreate(activity, r.state);           }        ...        return activity;}

performLaunchActivity方法中,注释1获取Activity信息。 注释2获取Activity 上下文。注释3获取到ClassLoader 类加载器对象。注释4使用ClassLoader(类加载器)加载出Activity,再使用反射new出Activity。注释5调用Activity的onCreate方法。

##Instrumentationpublic void callActivityOnCreate(Activity activity, Bundle icicle) {        prePerformCreate(activity);               activity.performCreate(icicle);  //1        postPerformCreate(activity);}

注释1处,调用Activity中performCreate方法

##Activityfinal void performCreate(Bundle icicle) {        performCreate(icicle, null);}##Activityfinal void performCreate(Bundle icicle, PersistableBundle persistentState) {        mCanEnterPictureInPicture = true;        restoreHasCurrentPermissionRequest(icicle);        //onCreate 生命周期方法被调用        if (persistentState != null) {            onCreate(icicle, persistentState);        } else {            onCreate(icicle);        }        ...}

performCreate方法中会调用onCreate方法。到这里Activity的创建已经结束啦。

备注:文中Android源码版本9.0

cb5f6ca4-d600-497b-ac3a-0f90d293e6e7
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值