Activity 组件创建

2021-04-10  本文已影响0人  gczxbb

ActivityThread 类 performLaunchActivity() 方法。

步骤
1,创建 ContextImpl。
2,Applicaion 对象,(第一次),LoadedApk 类 makeApplication() 方法。
3,Activity 实例创建,(cl.loadClass(className).newInstance())。
4,Activity 类的 attach() 方法,组件赋值。
5,生命周期 onCreate() 方法,调用 Instrumentation 类 callActivityOnCreate()方法 ,用户调用 setContentView() 方法,初始化视图布局。

一、组件创建

创建三个 Object,ContextImpl (For Activity),Activity 和 Application (第一次启动)。

1,ContextImpl
private Context createBaseContextForActivity(ActivityClientRecord r, final 
        Activity activity) {
    ...
    //创建Activity ContextImpl
    ContextImpl appContext = ContextImpl.createActivityContext(
                this, r.packageInfo, displayId, r.overrideConfig);
    appContext.setOuterContext(activity);
    Context baseContext = appContext;
    ...
    return baseContext;
}

ContextImpl 的 createActivityContext() 方法,创建 Activity 内部 ContextImpl 实例。
Activity 继承ContextWrapper 装饰类,内部 mBase 是 ContextImpl 对象。
通过 attach() 方法,Activity 内部赋值,初始化 mBase。

2,Activity

根据 Intent 提供的 ComponentName 组件类名,在 Instrumentation 类的newActivity() 方法,实例化 Activity 。

public Activity newActivity(ClassLoader cl, String className,
                            Intent intent)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    String pkg = intent != null && intent.getComponent() != null
            ? intent.getComponent().getPackageName() : null;
    return getFactory(pkg).instantiateActivity(cl, className, intent);
}

通过AppComponentFactory工厂创建Activity实例。

public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
            @Nullable Intent intent)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Activity) cl.loadClass(className).newInstance();
}
3,Application

全局对象,App 进程初始化仅一次,继承 ContextWrapper。
LoadedApk 类的 makeApplication() 方法。

public Application makeApplication(boolean forceDefaultAppClass,
                                   Instrumentation instrumentation) {
    //已经初始化,直接返回
    if (mApplication != null) {
        return mApplication;
    }
    Application app = null;
    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        appClass = "android.app.Application";
    }
    try {
        java.lang.ClassLoader cl = getClassLoader();
        //创建App ContextImpl
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        app = mActivityThread.mInstrumentation.newApplication(
                cl, appClass, appContext);
        appContext.setOuterContext(app);
    } catch (Exception e) {
        
    }
    mApplication = app;
    if (instrumentation != null) {
        try {
            //触发Application的onCreate方法
            instrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
        }
    }
    return app;
}

Instrumentation 类的 newApplication() 方法,同样由 AppComponentFactory 组件工厂通过反射 newInstance() 方法,创建 Application 实例。
ContextImpl 类的 createAppContext() 方法创建 ContextImpl 实例。
仅在第一次启动App时,调用一次 Application 类的 onCreate() 方法。

public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    Application app = getFactory(context.getPackageName())
            .instantiateApplication(cl, className);
    app.attach(context);
    return app;
}

Application 类的 attach() 方法,attachBaseContext() 方法,初始化ContextWrapper 基类内部 mBase 对象 (ContextImpl)。

二、Activity 组件赋值

attach() 方法。

final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
    attachBaseContext(context);
    //创造窗体对象
    mWindow = new PhoneWindow(this);
    mWindow.setCallback(this);
    ...
    //参数赋值给Activity
    mUiThread = Thread.currentThread();
    mMainThread = aThread;
    mInstrumentation = instr;
    mToken = token;
    mApplication = application;
    mIntent = intent;
    mComponent = intent.getComponent();
    mActivityInfo = info;
    mParent = parent;
    ...
    //创建Window内部的窗体管理者WindowManager
    mWindow.setWindowManager( (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    
    //WindowManager同时赋值给Activity对象
    mWindowManager = mWindow.getWindowManager();
}

将 Ams 服务的回传参数和其他参数如 ContextImpl 向 Activity 赋值,同时创建PhoneWindow 窗体和 WindowManagerImpl 窗体管理者。
Activity 内部绑定对象包括 Context、Instrumentation、Intent、Application、ActivityInfo、ActivityThread、IBinder 对象 token。


任重而道远

上一篇下一篇

猜你喜欢

热点阅读