Activty启动到显示的过程[一]

startActivity(Intent intent)启动一个Activity,然后会通过Instrumentaion和ActivityTaskManagerService通信,通过ActivityStarter执行启动流程。

流程图:
在这里插入图片描述

ActivityStarter在executeRequest()方法中实例化ActivityRecord, ActivityStack。

ActivityRecord,ActivityStack关系图

ActivityRecord,ActivityStack类关系图:

在这里插入图片描述

Token

ActivityRecord继承WindowToken类,在ActivityRecord构造函数中通过Intent参数初始化WindowToken的token变量,token是一个IBinder对象。

//WindowToken.java

class WindowToken extends WindowContainer<WindowState> {
    
    
    // The actual token.
    final IBinder token;
}

尽管ActivityRecord继承了WindowToken对象,但是它还是另外声明了一个自己的Token变量appToken,appToken和父类WindowToken的token变量都在ActivityRecord对象的构造方法中初始化,他们指向同一个实例化的对象,appToken是ActivityRecord的嵌套类ActivityRecord.Token,对比IBinder多实现了一些自己的方法attach(ActivityRecord activity);tokenToActivityRecordLocked(Token token);toString()等。

//ActivityRecord.java    

final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {
    
    
    // TODO: rename to mActivityToken
    final ActivityRecord.Token appToken;
    
    ActivityRecord() {
    
    
        super(_service.mWindowManager, new Token(_intent).asBinder(), TYPE_APPLICATION, true,
                null /* displayContent */, false /* ownerCanManageAppTokens */);
        appToken = (Token) token;
    }
    
	static class Token extends IApplicationToken.Stub {
    
    
        private WeakReference<ActivityRecord> weakActivity;
        private final String name;
        private final String tokenString;

        Token(Intent intent) {
    
    
            name = intent.getComponent().flattenToShortString();
            tokenString = "Token{" + Integer.toHexString(System.identityHashCode(this)) + "}";
        }
    }
}


//IApplicationToken.aidl
    interface IApplicationToken
    {
    
    
      String getName();
    }

Token为什么是binder对象?

可以理解为Token的设计目的是为了唯一的指定一个Activity,在Activity启动到显示的过程中,Token在ActivityRecord实例化的同时被初始化,后面还有许多地方都需要Token对象:

ClientTransaction.obtain(next.app.getThread(), next.appToken); //next.appToken被赋值给Activity.mToken
addWindow()

在Android系统中,binder不仅仅用来跨进程通信,binder对象的一个有趣属性是,每个实例在系统中的所有进程中都维护一个惟一的标识,无论它跨越了多少进程边界或它去了哪里,这为系统的安全性做出了保证,不能被伪造,避免了安全漏洞,这不是String对象能够做到的。参考:https://www.androiddesignpatterns.com/2013/07/binders-window-tokens.html#footnote5

可以理解为Activity, ActivityRecord, Token都是一一对应的关系。

ActivityRecord,ActivityStack初始化

ActivityStack在ActivityStarter类的startActivityInner()方法中被实例化,赋值给其mTargetStack变量:

        if (mTargetStack == null) {
    
    
            mTargetStack = getLaunchStack(mStartActivity, mLaunchFlags, targetTask, mOptions);
        }

ActivityStack被实例化后,父类WindowContainer回调子类ActivityRecord和Task覆盖的onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent)方法,初始化ActivityRecord中的类变量task,Task中的类变量mResumedActivity。ActivityRecord类和Task类就这样相互关联起来了。父类WindowContainer的类变量mChildren也被更新,mChildren保存着当前WindowContainer实例的所有Task对象。

//ActivityRecord.java
	@Override
    void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
    
    
        final Task oldTask = oldParent != null ? (Task) oldParent : null;
        final Task newTask = onParentChanged != null ? (Task) newParent : null;
        this.task = newTask;
        ...
    }
//Task.java
	@Override
    void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
    
    
    		...
            if (newParent != null) {
    
    
                final Task newParentTask = ((WindowContainer) newParent).asTask();
                if (newParentTask != null) {
    
    
                    final ActivityRecord top = newParentTask.getTopNonFinishingActivity(
                            false /* includeOverlays */);
                    if (top != null && top.isState(RESUMED)) {
    
    
                        newParentTask.setResumedActivity(top, "addedToTask");
                    }
                }
                ...
       		}
       		...
    }

ActivityRecord和ActivityStack都被初始化后,RootWindowContainer通过父类WindowContainer的类变量mChildren判断当前需要被显示的ActivityStack,调用其resumeTopActivityUncheckedLocked()方法。

隐藏其他Activity

在一个Activity显示出来之前,需要隐藏之前显示的Activity,回调其onPause()方法。

ActivityStack对象resumeTopActivityInnerLocked()方法中,通过TaskDisplayArea.pauseBackStacks(userLeaving, next);,遍历mChildren中所有的Task对象,判断这些Task中是否存在mResumedActivity,如果存在,通过ClientLifecycleManager隐藏这个Activity。PauseActivityItem在execute()后,postExecute()方法会继续调用RootWindowContainer类的resumeFocusedStacksTopActivities()方法,执行对应Activity的显示操作。

进程,线程初始化

在一个Activity显示出来之前,需要确定进程和主线程是否已经准备好。

通过ActivityRecord类的attachedToProcess()方法判断当前ActivityRecord对象的进程和线程是否准备好,如果准备好了,通过ApplicationThread和appToken参数与应用进程通信,回调对应生命周期方法(onNewIntent()等),ClientLifecycleManager执行ResumeActivityItem事务,否则需要调用ActivityStackSupervisor类startSpecificActivity()方法进一步判断进程和线程状态,调用ActivityTaskManagerService.startProcessAsync()启动新进程。

//ActivityRecord.java
    boolean hasProcess() {
    
    
        return app != null;
    }

    boolean attachedToProcess() {
    
    
        return hasProcess() && app.hasThread();
    }
//ActivityStack.java

	@GuardedBy("mService")
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    
    
    	...
    	boolean pausing = taskDisplayArea.pauseBackStacks(userLeaving, next);
        if (mResumedActivity != null) {
    
    
            pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);
        }
        if (pausing) {
    
    
        	...
        }
        
        if (next.attachedToProcess()) {
    
    
            try{
    
    
                
                final ClientTransaction transaction =
                        ClientTransaction.obtain(next.app.getThread(), next.appToken);	//ApplicationThread!
                // Deliver all pending results.
                ArrayList<ResultInfo> a = next.results;
                if (a != null) {
    
    
                    final int N = a.size();
                    if (!next.finishing && N > 0) {
    
    
                        if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                                "Delivering results to " + next + ": " + a);
                        transaction.addCallback(ActivityResultItem.obtain(a));
                    }
                }

                if (next.newIntents != null) {
    
    
                    transaction.addCallback(
                            NewIntentItem.obtain(next.newIntents, true /* resume */));	//onNewIntent()
                }
                transaction.setLifecycleStateRequest(
                        ResumeActivityItem.obtain(next.app.getReportedProcState(),
                                dc.isNextTransitionForward()));
                mAtmService.getLifecycleManager().scheduleTransaction(transaction);
            } catch (Exception e) {
    
    
                mStackSupervisor.startSpecificActivity(next, true, false);
                return true;
            }
        } else {
    
    
            mStackSupervisor.startSpecificActivity(next, true, true);
        }
        return true;
    }

system_server进程和zygote进程通信后,zygote以“android.app.ActivityThread”为入点fork出一个新的进程,新进程启动首先调用ActivityThread的main()方法。其中Looper.prepareMainLooper(); Looper.loop();初始化主线程。

// ActivityThread.java

    @UnsupportedAppUsage
    final ApplicationThread mAppThread = new ApplicationThread();

	public static void main(String[] args) {
    
    
    	// Install selective syscall interception
    	AndroidOs.install();
    	...
    	Looper.prepareMainLooper();
    
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);
    	if (sMainThreadHandler == null) {
    
    
            sMainThreadHandler = thread.getHandler();
        }
        Looper.loop();
	}

	@UnsupportedAppUsage
    private void attach(boolean system, long startSeq) {
    
    
        ...
        	final IActivityManager mgr = ActivityManager.getService();
            try {
    
    
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
    
    
                throw ex.rethrowFromSystemServer();
            }
        ...
    }

thread.attach(false, startSeq);获取系统服务AMS对象attachApplication(),传递的参数mAppThread是一个ApplicationThread对象,ApplicationThread是ActivityThread的内部类,也是一个Binder对象。在此处它是作为Activitythread和AMS通信的桥梁,ApplicationThread和ActivityThread二者间通过Handler

“H”通信。

//ActivityManagerService.java

	@GuardedBy("this")
    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
    
    
        	...
            AppDeathRecipient adr = new AppDeathRecipient(
                    app, pid, thread);
            thread.asBinder().linkToDeath(adr, 0);
            app.deathRecipient = adr;
        	...
            thread.bindApplication(processName, appInfo, providerList,
                        instr2.mClass,
                        profilerInfo, instr2.mArguments,
                        instr2.mWatcher,
                        instr2.mUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.compat, getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.mDisabledCompatChanges);
            ...
            app.makeActive(thread, mProcessStats);
            mProcessList.updateLruProcessLocked(app, false, null);
        	...
    }

attachApplicationLocked()创建app死亡通知AppDeathRecipient(进程被杀死后通知AMS),通过thread(IApplicationThread对象)与app进程通信bindApplication(),ActivityThread调用handleBindApplication(),最终会回调Application对象的onCreate()生命周期方法。

更新对应进程的LRU,OomAdj等相关属性,调用ProcessRecord对象makeActive(thread, mProcessStats);方法,将thread对象赋值给WindowProcessController类的mThread变量。

//WindowProcessController.java

	// The actual proc...  may be null only if 'persistent' is true (in which case we are in the
    // process of launching the app)
    private IApplicationThread mThread;

到这里进程和线程都已经准备好了,是时候真正启动Activity了。

realStartActivityLocked

//ActivityStackSupervisor.java
	boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
    
    
        ...
        final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), 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, proc.getReportedProcState(),
                        r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                        r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));        
        lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
        clientTransaction.setLifecycleStateRequest(lifecycleItem);
        
        // Schedule transaction.
        mService.getLifecycleManager().scheduleTransaction(clientTransaction);
   		...
    }

ClientTransaction对象添加LaunchActivityItem回调,LaunchActivityItem.execute()方法中会调用ActivityThread的handleLaunchActivity()方法,最后会调用Activity的生命周期方法onCreate()。

ClientTransaction对象setLifecycleStateRequest(ResumeActivityItem),设置Activity的resume状态。

最终ActivityThread调用handleResumeActivity()方法通过系统服务WMS的addView()方法显示Activity界面。

//ActivityThread.java
	@Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
    
    
        ...
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
        final Activity a = r.activity;
        if (r.window == null && !a.mFinished && willBeVisible) {
    
    
            if (a.mVisibleFromClient) {
    
    
                if (!a.mWindowAdded) {
    
    
                    a.mWindowAdded = true;
		            wm.addView(decor, l);
                } else {
    
    
                    // The activity will get a callback for this {@link LayoutParams} change
                    // earlier. However, at that time the decor will not be set (this is set
                    // in this method), so no action will be taken. This call ensures the
                    // callback occurs with the decor set.
                    a.onWindowAttributesChanged(l);
                }
            }
        }
        ...
    }

performResumeActivity()方法中会通过Instrumentation回调Activity中的onResume()和onPostResume()方法,然后才是addView(),可见在生命周期方法onResume()和onPostResume()被调用时,当前Activity对用户依然是不可见的。

Activity启动流程中可以看到system_server, zygote, app三个进程相互通信协作,ActivityTaskManagerService, ActivityManagerService, WindowManagerService等关键服务协同工作,token作为Activity的唯一标识贯穿其中。

猜你喜欢

转载自blog.csdn.net/qq_36063677/article/details/125638137