美文网首页
Activity启动过程 (以及Activity Activit

Activity启动过程 (以及Activity Activit

作者: yangLiHai | 来源:发表于2020-03-23 17:18 被阅读0次

    Activity启动过程

    (以及Activity ActivityThread Window WindowManager viewRootImpl View 之间的关系)

    ActivityThread是程序的入口,在其main函数中,

    1. 初始化looper,并开启loop函数,以及new出自身的实例,调用了attach方法,部分代码如下
    Looper.prepareMainLooper();
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
    Looper.loop();
    

    创建新的Activity之前,会先初始化application(如果不存在)。
    在创建Activity的过程中,首先调用
    scheduleLaunchActivity()
    之后便调用
    handleLaunchActivity()

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        handleConfigurationChanged(null, null);
        //初始化 WindowManagerService,主要是获取到 WindowManagerService 代理对象
        WindowManagerGlobal.initialize();
        //初始化Activity
        Activity a = performLaunchActivity(r, customIntent);
    
        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            //显示布局
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);
           
        }
    }
    

    在performLaunchActivity 方法中,会new一个activity实例出来,并执行attach方法

    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);
        }
    }
    ......
    activity.attach(appContext, this, getInstrumentation(), r.token,
                            r.ident, app, r.intent, r.activityInfo, title, r.parent,
                            r.embeddedID, r.lastNonConfigurationInstances, config,
                            r.referrer, r.voiceInteractor, window, r.configCallback);
    

    Activity.attach方法初始化了window,

    mWindow = new PhoneWindow(this, window, activityConfigCallback);
    mWindow.setWindowManager(
        (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
        mToken, mComponent.flattenToString(),
        (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    if (mParent != null) {
        mWindow.setContainer(mParent.getWindow());
    }
    mWindowManager = mWindow.getWindowManager();
    

    window是一个抽象类,具体实现是PhoneWindow,Android中不论是activity还是dialog,用的都是phoneWindow。同时得到一个 WindowManager 对象,WindowManager 是一个抽象类,这个 WindowManager 的具体实现是在 WindowManagerImpl 中

    public void setWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) {
        mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
    }
    

    每个 Activity 会有一个 WindowManager 对象,这个 mWindowManager 就是和 WindowManagerService 进行通信,也是 WindowManagerService 识别 View 具体属于那个 Activity 的关键,创建时传入 IBinder 类型的 mToken。

    在执行完这些后,就执行完了activity的attach方法,然后回到performLaunchActivity方法中继续,

    if (r.isPersistable()) {
        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
    } else {
        mInstrumentation.callActivityOnCreate(activity, r.state);
    }
    

    这个方法会回调activity的onCreate方法, 通常我们在onCreate中设置contentView,
    把布局设置给activity,其实这个时候只是调用了window来给window设置布局:
    Activity.setContentView():

    public void setContentView(@LayoutRes int layoutResID) {
        getWindow().setContentView(layoutResID);        
        initWindowDecorActionBar();    
    }
    

    PhoneWindow.setContentView():

    public void setContentView(int layoutResID) {
        ...    
        installDecor(); 
        ... 
    }
    

    installDecor方法初始化DectorView和mContentParent,mContentParent是DecorView的子view。
    这时只是创建了 PhoneWindow,和DecorView,但目前二者也没有任何关系,产生关系是在ActivityThread.performResumeActivity 中,再调用 r.activity.performResume(),调用 r.activity.makeVisible,将 DecorView 添加到当前的 Window 上。

    至此Activity.onCreate方法执行完毕,ActivityThread的performLaunchActivity和handleLaunchActivity从逻辑上基本执行完。
    总结下:初始化了Activity,给Activity初始化了window,WindowManager。为window初始化了DecorView

    执行完这些之后会执行ActivityThread.handleStartActivity 以及 performStartActivity这两个方法,对应的会执行Activity.onStart方法。这几个不涉及UI部分,暂不赘述。

    紧接着,就到了handleResumeActivity,

    final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) {
        //执行到 onResume()
        ActivityClientRecord r = performResumeActivity(token, clearHide);
    
        if (r != null) {
            final Activity a = r.activity;
            boolean willBeVisible = !a.mStartedActivity;
            ...
            if (r.window == null && !a.mFinished && willBeVisible) {
                r.window = r.activity.getWindow();
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (a.mVisibleFromClient) {
                    a.mWindowAdded = true;
                    wm.addView(decor, l);
                }
    
            }
            ...
            if (!r.activity.mFinished && willBeVisible
                    && r.activity.mDecor != null && !r.hideForNow) {
                ...
                mNumVisibleActivities++;
                if (r.activity.mVisibleFromClient) {
                    //添加视图,详见下面分析
                    r.activity.makeVisible(); 
                }
            }
    
            //resume 完成
            if (reallyResume) {
                  ActivityManagerNative.getDefault().activityResumed(token);
            }
        } else {
            ...
        }
    }
    

    Activity.makeVisible():

    void makeVisible() {
        if (!mWindowAdded) {
            ViewManager wm = getWindowManager();
            wm.addView(mDecor, getWindow().getAttributes());
            mWindowAdded = true;
        }
        mDecor.setVisibility(View.VISIBLE);
    }
    

    在此方法中会调用performResumeActivity,performResumeActivity中回调Activity.onResume。
    在这这些方法中,首先会吧Activity的dector指向window的DectorView,
    然后通过WindowManager添加。WindowManager 的 addView 的具体实现在 WindowManagerImpl 中,而 WindowManagerImpl 的 addView 又会调用 WindowManagerGlobal.addView()。

    WindowManagerGlobal.addView():

    public void addView(View view, ViewGroup.LayoutParams params,Display display, Window parentWindow) {
        ...
        ViewRootImpl root = new ViewRootImpl(view.getContext(), display);        
        view.setLayoutParams(wparams);    
        mViews.add(view);    
        mRoots.add(root);    
        mParams.add(wparams);        
        root.setView(view, wparams, panelParentView);
        ...
    }
    

    这个过程创建一个 ViewRootImpl,并将之前创建的 DecoView 作为参数传入,以后 DecoView 的事件都由 ViewRootImpl 来管理了,比如,DecoView 上添加 View,删除 View。

    ViewRootImpl 实现了 ViewParent 这个接口。普通的view的parent是他的容器布局,DecorView的parent是ViewRootImpl,在

        root.setView(view, wparams, panelParentView);
    

    这个方法执行中,进行了parent绑定ViewRootImpl。

    执行完之后,在通过其他方式显示在屏幕上。

    相关文章

      网友评论

          本文标题:Activity启动过程 (以及Activity Activit

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