美文网首页
Activity 组件创建

Activity 组件创建

作者: gczxbb | 来源:发表于2021-04-10 21:27 被阅读0次

    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。


    任重而道远

    相关文章

      网友评论

          本文标题:Activity 组件创建

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