Activity的view添加到window

在“Activity中view的加载”文章中可知,当用户在Activity中提供的view添加到DecorView后,view的加载就完成,再经过绘制就能显示出来了。那么DecorView又是如何添加到窗口中的或者说Activity关联的view又是如何被添加到窗口中的?

Activitythread的scheduleLaunchActivity方法负责启动Activity,经过Handerl处理执行到handleLaunchActivity

Activity a = performLaunchActivity(r, customIntent);
handleResumeActivity(r.token, false, r.isForward,!r.activity.mFinished && !r.startsNotResumed);

performLaunchActivity会创建待启动Activity类的一个实例,并调用其attach方法进行初始化,然后调用Activity的onCreate,onStart方法,在onCreate中会调用用户实现的setContentView,在setContentView中会创建Activity关联的DecorView。handleResumeActivity会调用onResume方法,让Activity处于可见状态并把其关联的DecorView添加到WindowManager中。attach方法做了很多工作,重点是创建了关联的window对象即PhoneWindow对象,获得关联的WindowManager对象,主要代码:

mWindow = PolicyManager.makeNewWindow(this);
mWindow.setCallback(this);
mWindowManager = mWindow.getWindowManager();

makeNewWindow的过程创建了PhoneWindow对象,setCallback把Activity对象传递到关联的Window对象中便于窗口的状态发生改变时能够通知Activity,getWindowManager得到WindowManager对象。继续看如何添加view的

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);
	}

首先获得关联的window对象和根view并把view的属性设为不可见,因为此时还没有加入到窗口中,所以设为不可见。获得关联的WindowManager对象,获得窗口的属性并设窗口类型为“应用程序窗口”,最后调用WindowManager的addView方法把Activity的view添加到窗口中,并置标志位mWindowAdded为true,表示view添加成功。有的文章中提到在Activity的makeVisible中添加view,这个不是完全正确

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

mWindowAdded已经为true了,所以不会在执行添加动作,makeVisible的重要工作让decorview可见。读到此处可知,先是让Activity可见,然后view才能可见。再看WindowManager的addView的具体实现,WindowManager的实现为WindowManagerImpl,添加、删除、更新窗口都是在这个类中进行的,这个类的实际的操作还是由WindowManagerGlobal进行,相关代码:

root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
root.setView(view, wparams, panelParentView);

创建view关联的ViewRootImpl对象并初始化,设置view的布局属性,把view添加到mViews列表中保存起来,ViewRootImpl对象添加到mRoots列表中,布局参数存储到mParams列表中,再把view传递到ViewRootImpl的setView中,看setView做了什么

mAttachInfo.mRootView = view;
mAdded = true;
requestLayout();

把view放在AttachInfo对象中保存起来,AttachInfo是View的内部类,其作用是保存即将被添加到窗口中的view的信息的。mAdded表示添加成功的标志,requestLayout方法很重要,会刷新view树,对view进行测量、布局、绘制,经过这个步骤后,用户提供的视图显示出来。

res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, getHostVisibility(), mDisplay.getDisplayId(), mAttachInfo.mContentInsets, mInputChannel);

addToDisplay的实现在Session中,这里是一个binder通信过程,Session的addToDisplay会传递到WindowManagerService的addWindow,添加窗口真实在这里发生的。从WindowManagerGlobal到WindowManagerService这几个过程可以看到,添加view变成了添加窗口,view都被保存在列表中,在创建每一个ViewRootImpl对象时都会创建对应的window对象

mWindow = new W(this);

最终在WindowManagerService的addWindow中完成窗口的添加

win = new WindowState(this, session, client, token,attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
mWindowMap.put(client.asBinder(), win);

用传递过来的窗口对象client作为参数创建了一个WindowState对象,然后把该对象作为值,把传递过来的窗口IBinder句柄作为键,作为一个键值对放在HashMap中保存起来,等下次使用的时候就可以从HashMap中根据窗口IBinder句柄取出对应的窗口对象。从这里可以看出,添加窗口的过程实际上变成了添加WindowState,WindowState实际上就表示一个窗口,这个窗口代表了被添加的窗口,也就是说,添加view最后变成添加窗口。window只是一个抽象的概念,其存在形式为view,添加view变成了添加窗口。窗口添加好后,相关事件就可以通过窗口传递给viewRootIml,再由viewRootIml传递给view。比如窗口焦点事件,如果焦点发生了变化,事件就会通过WindowState回调给上面参数client,client就是IWindow对象,IWindow对象传递给viewRootIml,viewRootIml又会传递给view。

本文的标题是“Activity的view添加到window中”,可以理解为添加Activity关联的窗口到窗口管理器中。在这个过程中会把decorview显示出来并把用户提供的视图绘制出来。

回答艺术开发探索的问题,一个应用有多少个window?

一个窗口对应一个view,一个view对应一个viewRootImpl,每个Activity启动的时候会关联一个窗口,那么每个Activity都会对应一个窗口,如果有N个Activity就会有N个窗口,但是窗口并不都是同时存在的,只有当Activity处于活动或者可见状态时窗口才会存在。一个窗口对应一个view,这里的view不是开发者写的textview或者button,而是根decorview。除了Activity,还有各种dialog,toast,弹出式菜单等,这些UI都会有对应的窗口,只要能想到和用户交互的地方都会存在窗口的概念。所以一个应用包含多个窗口,具体数目看这个应用有多少个Activity、dialog、toast等,而且这些视图必须处于活动或可见状态。

备注:可以验证这个说法,写一个小Demo,然后在创建WindowState和Decorview地方加上打印,每次启动Activity会不会打印到。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧农业是一种结合了现代信息技术,包括物联网、大数据、云计算等,对农业生产过程进行智能化管理和监控的新模式。它通过各种传感器和设备采集农业生产中的关键数据,如大气、土壤和水质参数,以及生物生长状态等,实现远程诊断和精准调控。智慧农业的核心价值在于提高农业生产效率,保障食品安全,实现资源的可持续利用,并为农业产业的转型升级提供支持。 智慧农业的实现依赖于多个子系统,包括但不限于设施蔬菜精细化种植管理系统、农业技术资料库、数据采集系统、防伪防串货系统、食品安全与质量追溯系统、应急追溯系统、灾情疫情防控系统、农业工作管理系统、远程诊断系统、监控中心、环境监测系统、智能环境控制系统等。这些系统共同构成了一个综合的信息管理和服务平台,使得农业生产者能够基于数据做出更加科学的决策。 数据采集是智慧农业的基础。通过手工录入、传感器自动采集、移动端录入、条码/RFID扫描录入、拍照录入以及GPS和遥感技术等多种方式,智慧农业系统能够全面收集农业生产过程中的各种数据。这些数据不仅包括环境参数,还涵盖了生长状态、加工保存、检验检疫等环节,为农业生产提供了全面的数据支持。 智慧农业的应用前景广阔,它不仅能够提升农业生产的管理水平,还能够通过各种应用系统,如库房管理、无公害监控、物资管理、成本控制等,为农业生产者提供全面的服务。此外,智慧农业还能够支持政府监管,通过发病报告、投入品报告、死亡报告等,加强农业产品的安全管理和质量控制。 面对智慧农业的建设和发展,存在一些挑战,如投资成本高、生产过程标准化难度大、数据采集和监测的技术难题等。为了克服这些挑战,需要政府、企业和相关机构的共同努力,通过政策支持、技术创新和教育培训等手段,推动智慧农业的健康发展。智慧农业的建设需要明确建设目的,选择合适的系统模块,并制定合理的设备布署方案,以实现农业生产的智能化、精准化和高效化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值