Activity启动流程要点

一、Activity启动流程 

  • Activity的启动流程一般是通过调用startActivity或者是startActivityForResult来开始的
  • startActivity内部也是通过调用startActivityForResult来启动Activity,只不过传递的requestCode小于0
  • Activity的启动流程涉及到多个进程之间的通讯这里主要是ActivityThread与ActivityManagerService之间的通讯
  • ActivityThread向ActivityManagerService传递进程间消息通过ActivityManagerNative,ActivityManagerService向ActivityThread进程间传递消息通过IApplicationThread。
  • ActivityManagerService接收到应用进程创建Activity的请求之后会执行初始化操作,解析启动模式,保存请求信息等一系列操作。
  • ActivityManagerService保存完请求信息之后会将当前系统栈顶的Activity执行onPause操作,并且IApplication进程间通讯告诉应用程序继承执行当前栈顶的Activity的onPause方法;(A到B界面,打开B那么A得先Pause)
  • ActivityThread接收到SystemServer的消息之后会统一交个自身定义的Handler对象处理分发;
  • ActivityThread执行完栈顶的Activity的onPause方法之后会通过ActivityManagerNative执行进程间通讯告诉ActivityManagerService,栈顶Actiity已经执行完成onPause方法,继续执行后续操作;
  • ActivityManagerService会继续执行启动Activity的逻辑,这时候会判断需要启动的Activity所属的应用进程是否已经启动,若没有启动则首先会启动这个Activity的应用程序进程(毕竟可以多进程);
  • ActivityManagerService会通过socket与Zygote继承通讯,并告知Zygote进程fork出一个新的应用程序进程,然后执行ActivityThread的main()方法;
  • 在ActivityThread.main方法中执行初始化操作,初始化主线程异步消息,然后通知ActivityManagerService执行进程初始化操作;
  • ActivityManagerService会在执行初始化操作的同时检测当前进程是否有需要创建的Activity对象,若有的话,则执行创建操作;
  • ActivityManagerService将执行创建Activity的通知告知ActivityThread,然后通过反射机制创建出Activity对象,并执行Activity的onCreate方法,onStart方法,onResume方法;
  • ActivityThread执行完成onResume方法之后告知ActivityManagerService onResume执行完成(新界面展示),开始执行栈顶Activity的onStop方法(这个老界面即将走入后台,新界面马上展示);
  • ActivityManagerService开始执行栈顶的onStop方法并告知ActivityThread;
  • ActivityThread执行真正的onStop方法(A调用stop)

二、Activity布局创建流程

主要代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);//Activity.onCreate
    setContentView(R.layout.activity_main);
}

  1.  当ActivityManagerService接收到启动Activity的请求之后会通过IApplicationThread进程间通讯告知ApplicationThread并执行handleLauncherActivity方法;
  2. handleLauncherActivity方法内部调用了performLaunchActivity方法;
  3. performLaunchActivity方法里通过反射的机制创建的Activity,并调用了Activity的attach方法;
    1. 初始化了一些Activity的成员变量,主要是mWindow对象,并且mWindow的成员实例是PhoneWindow实例;
  4. performLaunchActivity调用mInstrumentation.callActivityOnCreate(activity, r.state);在里面调用performCreate方法,方法里实现onCreate的回调。从这儿开始走到OnCrete方法。
  5. 那么来第一行,super.onCreate()里面主要就是做一个初始化,并且之后会执行一个判断逻辑,若Activity的mCalled为false,则会抛出我们刚刚捕获的异常,那么这个mCalled成员变量是在什么时候被赋值的呢?好吧,就是在Activity的onCreate方法赋值的,所以我们在实现自己的Activity的时候只有调用了super.onCreate方法才不会抛出这个异常,反过来说,我们实现自己的Actiivty,那么一定要在onCreate方法中调用super.onCreate方法。
  6. 接下来是setContentView()方法。
  7. public void setContentView(@LayoutRes int layoutResID) {
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    }

    这个getWindow就是phoneWindow,在activity.attach初始化的

  8. phoneWindow.setContentView--->installerDector()--->执行mDecor = generateDecor();生成一个DecorView。判断mContentParent(此处第一次为空)

    if (mContentParent == null) {
        mContentParent = generateLayout(mDecor);}调用此方法
  9. generateLayout()方法里通过调用LayoutInflater.inflate方法来加载布局文件到内存中,关于LayoutInflater.inflater是如何加载布局文件的,并且,通过对代码的分析,我们发现PhoneWindow中的几个成员变量:mDector,mContentRoot,mContentParent的关系mDector --> mContentRoot --> mContentParent(包含)
  10. activity到phonewidow再到mDector --> mContentRoot --> mContentParent,activity就拥有了布局文件的引用

     知识点: 

 

  • Activity的展示界面的特性是通过Window对象来控制的;
  • 每个Activity对象都对应这个一个Window对象,并且Window对象的初始化在启动Activity的时候完成,在执行Activity的onCreate方法之前;
  • 每个Window对象内部都存在一个FrameLayout类型的mDector对象,它是Acitivty界面的root view;
  • Activity中的window对象的实例是PhoneWindow对象,PhoneWindow对象中的几个成员变量mDector,mContentRoot,mContentParent都是View组件,它们的关系是:mDector --> mContentRoot --> mContentParent --> 自定义layoutView
  • LayoutInflater.inflate主要用于将布局文件加载到内存View组件中,也可以设定加载到某一个父组件中;
  • 典型的Activity的onCreate方法中需要调用super.onCreate方法和setContentView方法,若不调用super.onCreate方法,执行启动该Activity的逻辑会报错,若不执行setContentView的方法,该Activity只会显示一个空页面。

三、Activity的布局绘制流程

从AMS调Activity的onResume到App进程的主线程,有关Activity onResume生命周期的第一个方法就是handleResumeActivity,mWindowManager是在Activity的attach方法中被创建的 ,在获取了Activity的Window相关参数之后执行了r.activity.makeVisible()方法。

  //ActivityService.java  
@Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
        ......
        //1.最后会调到Activity的onResume
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);       
        ......
        final Activity a = r.activity;
        ......
        boolean willBeVisible = !a.mStartedActivity;
        if (!willBeVisible) {
            try {
                willBeVisible = ActivityManager.getService().willActivityBeVisible(
                        a.getActivityToken());
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
            2.获取WindowManagerImpl对象
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            l.softInputMode |= forwardBit;
            if (r.mPreserveWindow) {
                a.mWindowAdded = true;
                r.mPreserveWindow = false;
                ViewRootImpl impl = decor.getViewRootImpl();
                if (impl != null) {
                    impl.notifyChildRebuilt();
                }
            }
            if (a.mVisibleFromClient) {
                if (!a.mWindowAdded) {
                    a.mWindowAdded = true;
                    3.调用WindowManagerImpl的addView方法
                    wm.addView(decor, l);
                } 
                ......
            }
 if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
            r.activity.mVisibleFromServer = true;
            mNumVisibleActivities++;
            if (r.activity.mVisibleFromClient) {
                r.activity.makeVisible();
            }
        }
           ......
        }
      .......
    }

Activity执行onResume之后再ActivityThread中执行Activity的makeVisible方法。

  • //Activity.java
    void makeVisible() {
        if (!mWindowAdded) {
            ViewManager wm = getWindowManager();//这里的ViewManager对象是通过getWindowManager()方法获取的。是在Activity的attach方法方法中初始化的
            wm.addView(mDecor, getWindow().getAttributes());
            mWindowAdded = true;
        }
        mDecor.setVisibility(View.VISIBLE);//将mDecor给显示到界面上
    }
    
  •  wm.addView(mDecor, getWindow().getAttributes()); addView这里面调用了mGlobal.addView(view, params, mDisplay, mParentWindow);而mGlobal为WindowManagerGlobal,在mGlobal.addView里调用了root.setView。(ViewRootImpl)

  • 在root.setView里调用了调用了requestLayout方法,调用执行重绘的请求

  • @Override
    public void requestLayout() {
        if (!mHandlingLayoutInLayoutRequest) {
            checkThread();//检查是否UI线程
            mLayoutRequested = true;
            scheduleTraversals();
    这里面调用performTraversals方法,
    从这个方法开始我们的View经过大小测量,位置测量,
    界面绘制三个逻辑操作之后就可以展示在界面中了。
    
        }
    }

  • performTraversals的相关内容如下(绘制界面)

  • View的绘制流程包含了测量大小,测量位置,绘制三个流程;

  • Activity的界面绘制是从mDecor即根View开始的,也就是从mDecor的测量大小,测量位置,绘制三个流程;

  • View体系的绘制流程是从ViewRootImpl的performTraversals方法开始的;

  • View的测量大小流程:performMeasure --> measure --> onMeasure等方法;

  • View的测量位置流程:performLayout --> layout --> onLayout等方法;

  • View的绘制流程:onDraw等方法;

  • View组件的绘制流程会在onMeasure,onLayout以及onDraw方法中执行分发逻辑,也就是在onMeasure同时执行子View的测量大小逻辑,在onLayout中同时执行子View的测量位置逻辑,在onDraw中同时执行子View的绘制逻辑;

  • Activity中都对应这个一个Window对象,而每一个Window对象都对应着一个新的WindowManager对象(WindowManagerImpl实例);

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&岁月不待人&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值