Android中Window9问9答Word下载.docx
- 文档编号:16790393
- 上传时间:2022-11-26
- 格式:DOCX
- 页数:17
- 大小:24.90KB
Android中Window9问9答Word下载.docx
《Android中Window9问9答Word下载.docx》由会员分享,可在线阅读,更多相关《Android中Window9问9答Word下载.docx(17页珍藏版)》请在冰豆网上搜索。
注意system_alert_window这个权限。
否则要出错
5.尝试简单分析window的添加过程?
即window.addView()函数的执行过程:
1//首先我们要知道windwmanger本身就是一个接口,他的实现是交给WindowManagerImpl来做的。
2publicfinalclassWindowManagerImplimplementsWindowManager{
3
4
5//他的view方法一看,发现也是基本没做实际的addview操作是交给mGlobal来做的
6@Override
7publicvoidaddView(@NonNullViewview,@NonNullViewGroup.LayoutParamsparams){
8applyDefaultToken(params);
9mGlobal.addView(view,params,mDisplay,mParentWindow);
10}
11
12
13//发现这是一个工厂吗,到这里一看就明白了,WindowManagerImpl的实际操作都桥接给了WindowManagerGlobal来处理
14privatefinalWindowManagerGlobalmGlobal=WindowManagerGlobal.getInstance();
15
16//先看一下WindowManagerGlobal的重要变量,注意上面已经分析过了,WindowManagerGlobal本身自己是一个单例,全局唯一,
17//所以下面这些参数list,全局也是唯一的,mViews就是所有window对应的view,mRoots就是所有viewRootImpl,mParams就是这些
18//view的参数,dyingviews就是正在删除的对象,就是那种你调用了remove操作但是remove还没有操作完毕的那些view
19privatefinalArrayList<
View>
mViews=newArrayList<
();
20privatefinalArrayList<
ViewRootImpl>
mRoots=newArrayList<
21privatefinalArrayList<
WindowManager.LayoutParams>
mParams=
22newArrayList<
23privatefinalArraySet<
mDyingViews=newArraySet<
24
25
26
27
28//所以我们就看看WindowManagerGlobal源码里的addView是如何实现的
29publicvoidaddView(Viewview,ViewGroup.LayoutParamsparams,
30Displaydisplay,WindowparentWindow){
31if(view==null){
32thrownewIllegalArgumentException("
viewmustnotbenull"
33}
34if(display==null){
35thrownewIllegalArgumentException("
displaymustnotbenull"
36}
37if(!
(paramsinstanceofWindowManager.LayoutParams)){
38thrownewIllegalArgumentException("
ParamsmustbeWindowManager.LayoutParams"
39}
40
41finalWindowManager.LayoutParamswparams=(WindowManager.LayoutParams)params;
42//如果是子window就调整一下参数
43if(parentWindow!
=null){
44parentWindow.adjustLayoutParamsForSubWindow(wparams);
45}else{
46//Ifthere'
snoparentandwe'
rerunningonLorabove(orinthe
47//systemcontext),assumewewanthardwareacceleration.
48finalContextcontext=view.getContext();
49if(context!
=null
50&
&
context.getApplicationInfo().targetSdkVersion>
=Build.VERSION_CODES.LOLLIPOP){
51wparams.flags|=WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
52}
53}
54
55ViewRootImplroot;
56ViewpanelParentView=null;
57
58synchronized(mLock){
59//Startwatchingforsystempropertychanges.
60if(mSystemPropertyUpdater==null){
61mSystemPropertyUpdater=newRunnable(){
62@Overridepublicvoidrun(){
63synchronized(mLock){
64for(inti=mRoots.size()-1;
i>
=0;
--i){
65mRoots.get(i).loadSystemProperties();
66}
67}
68}
69};
70SystemProperties.addChangeCallback(mSystemPropertyUpdater);
71}
72
73intindex=findViewLocked(view,false);
74if(index>
=0){
75if(mDyingViews.contains(view)){
76//Don'
twaitforMSG_DIEtomakeit'
swaythroughroot'
squeue.
77mRoots.get(index).doDie();
78}else{
79thrownewIllegalStateException("
View"
+view
80+"
hasalreadybeenaddedtothewindowmanager."
81}
82//ThepreviousremoveView()hadnotcompletedexecuting.Nowithas.
83}
84
85//Ifthisisapanelwindow,thenfindthewindowitisbeing
86//attachedtoforfuturereference.
87if(wparams.type>
=WindowManager.LayoutParams.FIRST_SUB_WINDOW&
88wparams.type<
=WindowManager.LayoutParams.LAST_SUB_WINDOW){
89finalintcount=mViews.size();
90for(inti=0;
i<
count;
i++){
91if(mRoots.get(i).mWindow.asBinder()==wparams.token){
92panelParentView=mViews.get(i);
93}
94}
95}
96
97//这个代码充分说明了每一个window都对应着一个view和一个viewrootIMPL,window本身自己不存在,
98//他的意义就在于管理view,而管理view就要通过windowmanager最终走到windwmanagerglobal这里来完成管理
99root=newViewRootImpl(view.getContext(),display);
100
101view.setLayoutParams(wparams);
102
103mViews.add(view);
104mRoots.add(root);
105mParams.add(wparams);
106}
107
108//dothislastbecauseitfiresoffmessagestostartdoingthings
109try{
110//view的最终绘制是在viewrootimpl里完成的,所以这里view的绘制也是在这个里面完成的
111//我们在viewrootimpl里能找到setview的源码他在这个函数里调用了requetlayout
112root.setView(view,wparams,panelParentView);
113}catch(RuntimeExceptione){
114//BadTokenExceptionorInvalidDisplayException,cleanup.
115synchronized(mLock){
116finalintindex=findViewLocked(view,false);
117if(index>
118removeViewLocked(index,true);
119}
120}
121throwe;
122}
123}
124
125
126//而requestLayout里有scheduleTraversals方法这个就是view绘制的入口处
127publicvoidrequestLayout(){
128if(!
mHandlingLayoutInLayoutRequest){
129checkThread();
130mLayoutRequested=true;
131scheduleTraversals();
132}
133}
134
135//回到前面提到的setView那个函数
136//我们可以看到requestLayout结束以后mWindowSession.addToDisplay就有了这个方法的调用
137//实际上这个方法完成的就是一个window的添加。
138requestLayout();
139if((mWindowAttributes.inputFeatures
140&
WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL)==0){
141mInputChannel=newInputChannel();
142}
143try{
144mOrigWindowType=mWindowAttributes.type;
145mAttachInfo.mRecomputeGlobalAttributes=true;
146collectViewAttributes();
147res=mWindowSession.addToDisplay(mWindow,mSeq,mWindowAttributes,
148getHostVisibility(),mDisplay.getDisplayId(),
149mAttachInfo.mContentInsets,mAttachInfo.mStableInsets,mInputChannel);
150
151//然后我们很容易就发现这是一个接口并且代码一看就知道还是一个binder
152//所以实际上添加window的功能就是通过BInder是调用windwmangerservice的方法来完成的
153publicinterfaceIWindowSessionextendsandroid.os.IInterface
154{
155/**Local-sideIPCimplementationstubclass.*/
156publicstaticabstractclassStubextendsandroid.os.Binderimplementsandroid.view.IWindowSession
157{
158privatestaticfinaljava.lang.StringDESCRIPTOR="
android.view.IWindowSession"
;
159/**Constructthestubatattachittotheinterface.*/
160publicStub()
161{
162this.attachInterface(this,DESCRIPTOR);
163}
6.activity的window是如何创建的?
应用类的window创建过程:
1
2//activity的window创建由activityThread的performLaunchActivity方法开始
3privateActivityperformLaunchActivity(ActivityClientRecordr,IntentcustomIntent){
4......
5if(activity!
6ContextappContext=createBaseContextForActivity(r,activity);
7CharSequencetitle=r.activityInfo.loadLabel(appContext.getPackageManager());
8Configurationconfig=newConfiguration(mCompatConfiguration);
9if(DEBUG_CONFIGURATION)Slog.v(TAG,"
Launchingactivity"
10+r.activityInfo.name+"
withconfig"
+config);
11//其中最主要的就是attach方法注意是调用的activity的attach方法不是activitytherad的
12activity.attach(appContext,this,getInstrumentation(),r.token,
13r.ident,app,r.intent,r.activityInfo,title,r.parent,
14r.embeddedID,r.lastNonConfigurationInstances,config,
15r.referrer,r.voiceInteractor);
16
17......
18
19returnactivity;
20}
21
22
23finalvoidattach(Contextcontext,ActivityThreadaThread,
24Instrumentationinstr,IBindertoken,intident,
25Applicationapplication,Intentintent,ActivityInfoinfo,
26CharSequencetitle,Activityparent,Stringid,
27NonConfigurationInstanceslastNonConfigurationInstances,
28Configurationconfig,Stringreferrer,IVoiceInteractorvoiceInteractor){
29attachBaseContext(context);
30
31mFragments.attachActivity(this,mContainer,null);
32//这里一下就能看出来Acitity的window对象是由PolicyManager的makeNewWindow方法构造出来
33//有兴趣的还可以看一下这里set了很多接口都是我们熟悉的那些方法
34mWindow=PolicyManager.makeNewWindow(this);
35mWindow.setCallback(this);
36mWindow.setOnWindowDismissedCallback(this);
37mWindow.getLayoutInflater().setPrivateFactory(this);
38if(info.softInputMode!
=WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED){
39mWindow.setSoftInputMode(info.softInputMode);
40}
41if(info.uiOptions!
42mWindow.setUiOptions(info.uiOptions);
43}
44mUiThread=Thread.currentThread();
45
46mMainThread=aThread;
47mInstrumentation=instr;
48mToken=token;
49mIdent=ident;
50mApplication=application;
51mIntent=intent;
52mReferrer=referrer;
53mComponent=intent.getComponent();
54mActivityInfo=info;
55mTitle=title;
56mParent=parent;
57mEmbeddedID=id;
58mLastNonConfigurationInstances=lastNonConfigurationInstances;
59if(voiceInteractor!
60if(lastNonConfigurationInstances!
61mVoiceInteractor=lastNonConfigurationInstances.voiceInteractor;
62}else{
63mVoiceInteractor=newVoiceInteractor(voiceInteractor,this,this,
64Looper.myLooper());
65}
67
68mWindow.setWindowManager(
69(WindowManager)context.getSystemService(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android Window9