Framework入门03-Activity组件

3-1 说说Activity的启动流程

启动Activity会经历哪些生命周期回调

冷启动大致流程,涉及哪些组件,通信过程是怎么样的?

Activity启动过程中,生命周期回调的原理?

Activity.startActivity -> ActivityManagerNative.getDefault().startActivity 这里的ActivityManagerNative.getDefault()是ams的binder对象,即代理对象 -> mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply,O) ams将请求写入binder驱动

-> binder驱动回调到ams的 onTransact()方法,然后根据请求码执行 startActivity(app, callingPackage, intent,...)

-> ams里处理activity的关键方法 startSpecificActivityLocked(),这个方法里,先判断应用进程是否启动(ProcessRecord app不为空且app.thread不为空时进程已启动),然后再执行真正启动activity的方法realStartActivityLocked(r, app...)

-> 如果进程未启动,则先启动进程 mService.startProcessLocked(r.processName...)

-> 将启动入口entryPoint="android.app.ActivityThread"通过socket发送给zygote, 然后 Process.start(entryPoint,) 即向zygote发送启动应用进程的请求。(这里大致说一下zygote启动应用进程的步骤:fork应用进程并返回pid,会返回两次:pid==0时在子进程,即应用进程执行;pid不为0时,在父进程执行,即将pid的值赋给ams,告诉ams应用进程已启动。)后面这里还会通过mHandler发送一条延迟消息,即延迟10s的超时消息,如果应用进程向ams报告自己已启动,则会移除这条消息,若是没有移除,处理这条消息时会清理进程的信息,即进程启动失败了。

-> 应用进程启动,在ActivityThread的main方法里,准备MainLooper;new ActivityThread;attach(false) false表示不可取消;loop死循环。

-> 上一步的attach(false)是跨进程调用:ActivityManagerNative.getDefault()获取ams的binder对象,attachApplication(mAppThread),参数mAppThread是applicationThread对象,这样asm就持有了应用进程的binder对象。

-> attachApplicationLocked(IApplicationThread thread, int pid) 这个方法很重要:thread.bindApplication(....)跨进程调用到应用进程,然后初始化application实例。之后就是启动acticity组件,启动service组件,启动广播。

-> 启动acticity组件的方法是mStackSupervisor.attachApplicationLocked(app),app是ProcessRecord实例

-> ActivityRecord hr = stack.topRunningActivityLocked(null);//是需要启动的activity,然后进入realStartActivityLocked(hr, app, true,true);

-> app.thread.scheduleLaunchActivity(new Intent(r.intent), ...); app是ProcessRecord,thread是ApplicationThread

-> sendMessage(H.LAUNCH ACTIVITY,r);//将要启动activity的message发送到主线程

-> 主线程处理message:final ActivityClientRecord r = (ActivityClientRecord) msg.obj;r.packagelnfo = getPackagelnfoNoCheck(.….); handleLaunchActivity(r, null);

-> 在handleLaunchActivity()里:Activity a = performLaunchActivity(r, customIntent);handleResumeActivity(r.token, false...);

-> 在performLaunchActivity()里,newActivity,获取application实例,创建上下文,activity.attach(),mlnstrumentation.callActivityOnCreate(activity, r.state);//即activity.onCreate()回调, activity.performStart();//即activity.onStart()回调;

-> 接着看handleLaunchActivity()方法,最终会回调activity.onResume();

3-2 说说Activity的显示原理

需理解以下的概念:

Activity的显示原理(Window/DecorView/ViewRoot)

Activity的UI刷新机制(Vsync信号/Choreographer机制) / ˌkɒriˈɒɡrəfə(r) / 编舞者,舞蹈指导

UI的绘制原理(Measure/Layout/Draw)

Surface原理(Surface/SurfaceFlinger)

说说Activity的显示原理,弄清楚以下3个问题:

setContentView原理是什么?

setContentView(layoutResID)

-> getWindow().setContentView(layoutResID) //getWindow()返回mWindow,是在activity的attach(context)里初始化的;

-> setContentView(int layoutReslD){

installDecor();//创建decorView,将系统布局添加到decorView,根据findViewById找到mContentParent,mContentParent是系统布局里的一个子布局;

mLayoutlnflater.inflate(layoutResID, mContentParent);//生成view tree,将viewTree加入到mContentParent里

}

Activity在onResume之后才会显示的原因是什么?

ViewRoot是干嘛的,是View Tree的rootView么?

在handleResumeActivity()方法里:

-> handleResumeActivity(lBinder token,) {

ActivityClientRecord r = performResumeActivity(token,); //执行onResume()回调

final Activity a = r.activity;

if (r.window == null && !a.mFinished) {

r.window = r.activity.getWindow();

View decor = r.window.getDecorView();

ViewManager wm = a.getWindowManager();

a.mDecor = decor;

wm.addView(decor,); //decor加入到windowManager

}

r.activity.makeVisible();//设置为可见,只是触发一次重绘

}

-> windowManager的addView()方法:

void addView(View view,ViewGroup.LayoutParams params,) {

ViewRootlmpl root = new ViewRootlmpl(view.getContext(),);

root.setView(yiew, wparams, panelParentView);//将decorView交给viewRoot来管理

}

-> setView(View view, ){

requestLayout(); //触发一次绘制

mWindowSession.addToDisplay(mWindow,..); //是binder调用,

}

-> 在requestLayout()方法里:

requestLayout ->scheduleTraversals()

-> mChoreographer.postCallback(... mTraversalRunnable, null)//在vsync信号来时执行回调doTraversal()

-> performTraversals() //执行绘制

private void performTraversals() {

//向wms申请surface,即执行mWindowSession.relayout(...,mSurface);

//relayout执行完后,mSurface就有值了,接下来的绘制就有了buffer,

//然后在buffer上绘制完了就提交给surfaceFlinger,surfaceFlinger合成好图像后,

//就能写到屏幕的缓冲区,然后页面就能显示出来了。

relayoutWindow(params,...);

performMeasure(childWidthMeasureSpec,

performLayout(lp, desiredWindowWidth, ...);

performDraw();

}

-> 再接着看mWindowSession.addToDisplay(mWindow,..);

viewRoot持有mWindowSession,mWindowSession是wms返回的一个binder对象,给应用和wms来通信用的;

mWindow是一个binder对象,注册到wms后,应用端与wms就构成了双向调用。

WMS主要作用:分配surface;掌管surface显示顺序及位置尺寸等;控制窗口动画;输入事件分发。

3-3 应用的UI线程是怎么启动的

什么是UI线程?

答:UI线程就是刷新Ul所在的线程;UI是单线程刷新的。

对Activity来说,UI线程就是主线程;

对View来说,它的UI线程就是ViewRootlmpl创建的时候所在的线程;

可以得出结论:Activity的DecorView对应的ViewRootlmpl是在主线程创建的。

UI线程的启动流程,消息循环是怎么创建的?

Zygote fork进程 -> 启动binder线程 -> 执行入口函数

ActivityThread.main()方法里:Looper.prepareMainLooper();Looper.loop();

了解Android的U显示原理,UI线程和UI之间是怎么关联的?

ViewRootlmpl的创建:

ActivityThread.handleResumeActivity -> WindowManagerlmpl.addView -> WindowManagerGlobal.addView -> ViewRootlmpl的构造

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值