Activity、View、Window的理解一篇文章就够了

Activity、View、Window的理解一篇文章就够了,第1张

要了解这三者之间的关系,我们带着问题通过分析源码一步一步来揭开它们的神秘面纱!

文章有点长,首先要理解Activity、View、Window,我提出了一些问题,这篇文章可以解答如下问题:

1、为什么要设计Activity、View、Window?

2、Activity工作过程是什么样的?(理解Activity)

3、Window是什么?它的职能是什么?

4、View跟Window有什么联系?

5、Activity、View、Window三者如何关联?

用一句话来联系他们之间的关系:

一张图理清所有层级关系:

好了,接下来一步一步的分析,首先从大家最熟悉的Activity开始:

一个应用程序里所有的界面展示都来自于Activity,那Activity是如何工作的呢?

Activity工作过程:

要了解Activity工作过程,首先从启动开始,下面没有贴源码,因为本文章主题是三者之间的关系,而Activity东西太多了,就简单的讲一下。

启动:

从startActivity开始,它会调用到Instrumentation,然后Instrumentation通过Binder向AMS(ActivityManagerService)发请求,通过PIC启动Activity。而这个AIDL *** 作的方法定义在ApplicationThread中(里面包括了Activity所有的生命周期方法的调用)。然后通过Handle回到主线程启动activity。

因为中间流程太多,详细写出来容易造成“见其树木,而不见其森林”的局面。

启动Activity所执行的 *** 作:

1、从ActivityClientRecord中获取待启动的Activity组件信息

2、通过Instrumentation的newActivity方法使用类加载器创建Activity对象

3、通过LoadedApk的mackApplication方法来尝试创建Application对象(如果Application已经创建,则不会重复创建)

4、创建ContextImpl对象,并通过Activity的attach方法来完成一些重要数据的初始化(包括让Activity跟Window关联)

5、调用Activity的onCreate方法

Activity其他生命周期的调用都是通过Binder向AMS发请求,然后执行的PIC *** 作,最后从ApplicationThread对生命周期调用。

下面是重点:Activity、View、Window三者的关系。

View如何跟Activity关联起来的?

其实View并不是直接跟Activity关联起来的,而是通过Window这个中间人。如前面所说,View只是窗花,Window才是直接关联到Activity上的。那么:

View如何跟Window关联起来呢?

下面先了解一下Window,就可以理解这个问题了

Window如何跟Activity关联?

每一个Activity都包含了唯一一个PhoneWindow,这个就是Activity根Window(之所以是说根Window是因为在它上面可以增加更多其他的Window,例如:d出框(dialog))

那么,PhoneWindow如何跟Activity关联起来的呢?

来个最简单的,setContentView其实就让View与Window关联,Window跟Activity关联起来了。

那setContentView不是View跟Activity关联吗?

真相见Activity源码:

明显是将layout设置到Window上了,那这个 getWindow() 返回的Window是谁呢? 是不是前面提及PhoneWindow?

这么说来setContentView其实就是将View设置到Window上,Activity展示的其实是PhoneWindow上的内容。那么其实 setContentView 实际上是调用的 getWindow()setContentView。

PhoneWindow是个什么东西?它作为Activity跟View的中间人,它做了哪些工作?

首先 PhoneWindow 本身就是一个 Window。

从setContentView来分析:

这里的 mContentParent 其实是一个 ViewGroup。这么看来就简单了。PhoneWindow里面包含了一个ViewGroup,setContentView其实就是将layout设置到了这个ViewGroup上了。

我们再看看这张图:

DecorView是啥?

它直接跟PhoneWindow关联起来的,有了mContentParent,为啥还需要DecorView?

如图所见,DecorView它不仅包含了我们自己的布局,它还包含了titleBar。为啥需要?结构上的需要,更好的管理布局。

Window作为中间人,已经关联了Activity跟View了,那么如果处理Activity跟View之间的关系呢?

是时候揭开Window这个神秘面纱了:

之前提的PhoneWindow是继承于Window的,它是连接Activity跟View之间的桥梁。所有对View的一些 *** 作都需要借助这个桥梁。

为了更好的理解Window,我们先从Dialog入手。在Activity中展示一个对话框的流程是怎样的?

为啥从Dialog入手,因为它里面包含了Window,而且可以直接 *** 作Window里面的View,这样就能了解Window是如何控制View的,以及自定义Window怎么展示到Activity上(因为了解Dialog,就知道怎么让自定义的Window与Activity关联了)

我们省去所有的Dialog build的方法。直接从AlertDialogshow()方法开始:

AlertDialog构造方法里面最后执行的是这个构造方法,这里找到了亮点:

1、mWindow是啥?是不是PhoneWindow

首先AlertDialog是继承Dialog的,mWindow就是Dialog里面初始化的对象,看看是不是PhoneWindow,如果是,那么就可以猜到通过在PhoneWindow添加View就可以在Activity上展示了,因为经过上面分析Activity是跟PhoneWindow有关联的。带着问题继续分析源码:

2、AlertController是啥?

从这两个属性就知道了,设置Title、Message的。用过Dialog的人都知道他们是啥,就不多说了。

既然这样关联起来了,那么Window怎么对View *** 控的呢?

WindowManager是主角。

在Dialog build之后就将View设置进来了,继续追踪Dialog show()这个方法,这个方法会将View与Window相互联系:

mWindowManageraddView,看到这个方法,可以猜想到WindowManager是个啥玩意了。

总结:

1、为什么要设计Activity、View、Window?

Activity就像工匠,Window就像是窗户,View就像是窗花,LayoutInflater像剪刀,Xml配置像窗花图纸。

Android根据他们不同的职能让他们各斯其活,同时也相互配合展示给我们灵活、精致的界面。为啥这样设计?因为这样的结构更好管理。就像为啥需要使用MVP、MVVM、各种设计模式一样。

2、Activity工作过程是什么样的?

以Activity启动过程为例,Activity启动时是通过Binder向AMS(ActivityManagerService)发请求,通过PIC启动Activity的。

3、Window是什么?它的职能是什么?

Activity要管理View需要通过Window来间接管理的。Window通过addView()、removeView()、updateViewLayout()这三个方法来管理View的。

4、View跟Window有什么联系?

View需要通过Window来展示在Activity上。

5、Activity、View、Window三者如何关联?

Activity包含了一个PhoneWindow,而PhoneWindow就是继承于Window的,Activity通过setContentView将View设置到了PhoneWindow上,而View通过WindowManager的addView()、removeView()、updateViewLayout()对View进行管理。Window的添加过程以及Activity的启动流程都是一次IPC的过程。Activity的启动需要通过AMS完成;Window的添加过程需要通过WindowSession完成。

你竟然看完了,非常感谢你的支持,希望这篇文章对你有帮助~

————2020年3月11日 更新

最近建了微信公众号和微博,由我(卷子)和我的好朋友(樱桃)两只小程序媛经营的。

我们都喜欢程序员这个呆萌的群体,我们希望能给你带来技术上的帮助以及生活上的快乐。嘿嘿~唯一的私心就是 希望你能喜欢我们咯。

大哥,我先敬你一瓶,先干为尽

我的需求是在recyclerview下的子view中有多个EditText

提交数据的时候需要获取到每个EditText的内容

1第一种方式,直接在Activity中

获取item中跟布局

好吧,结果是不靠谱的,发现每次只能获取到看的见的 recyclerview的跟布局, 还未出现在我们视野的子view,获取为null,

2尝试第二种

但是在fragment中如果直接调用上面的方法,返回的view为空,我们需要用handler的postDelayed方法延迟获取。

结果还是不尽人意,看不见的item,依旧获取不了跟布局

3直接在Adapter中为item中的edittext添加 addTextChangedListener 监听方法

把设置的方法放在一个方法里面,然后把Id当做参数传进去,比如Ridtext1的话,可以这样用一个变量String

baseId="Rid",这个方法可以写成setConfig(String

strId){String

currentId=baseId+strId;

//后面的代码按下面来

}

然后再用下面的方法

public

static

int

getResourdIdByResourdName(Context

context,

String

ResName){

int

resourceId

=

0;

try

{

Field

field

=

RdrawableclassgetField(ResName);

fieldsetAccessible(true);

try

{

resourceId

=

fieldgetInt(null);

}

catch

(IllegalArgumentException

e)

{

logshowLogDebug("IllegalArgumentException:"

+

etoString());

}

catch

(IllegalAccessException

e)

{

logshowLogDebug("IllegalAccessException:"

+

etoString());

}

}

catch

(NoSuchFieldException

e)

{

logshowLogDebug("NoSuchFieldException:"

+

etoString());

}

return

resourceId;

}将currentId作为参数传入就可以了,这时在调用findViewById找,,,

采纳啊,大哥,写了这么多

Intent myIntent = new Intent(this, MyActivityclass);

private View getView(String id, Intent intent) {

return managerstartActivity(id, intent)getDecorView();

}

id自定义就好,intent用上面的指定是哪个Activity

今天想实现在view中返回上一个activity的功能,想了半天。因为在虽然view是包含于一个activity的,但是直接在view中用this取得的对象不是activity而是这个view,直接写activity的名字也不行。于是找到了这个方法并附上!

首先假设,view是在activity A中定义生成的。假设view的类叫做GameView,则在A中得oncreat()里,一定把activity对象传到了GameView的构造函数。

gameview=new GameView(this);

因为在view中,会有构造函数,只要将context传给新定义的activity,就能在view中 *** 作activity

public GameView(Context context) {

super(context);

Activity activity;

activity=(Activity) context;

}

以上就是关于Activity、View、Window的理解一篇文章就够了全部的内容,包括:Activity、View、Window的理解一篇文章就够了、获取Recyclerview下的子view、android怎么样获取当前activity下所有的textview控件等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9272789.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-26
下一篇2023-04-26

发表评论

登录后才能评论

评论列表(0条)

    保存