Android中Window9问9答.docx
- 文档编号:3884173
- 上传时间:2022-11-26
- 格式:DOCX
- 页数:17
- 大小:24.90KB
Android中Window9问9答.docx
《Android中Window9问9答.docx》由会员分享,可在线阅读,更多相关《Android中Window9问9答.docx(17页珍藏版)》请在冰豆网上搜索。
Android中Window9问9答
AndroidWindow9问9答
1.简述一下window是什么?
在android体系里扮演什么角色?
答:
window就是一个抽象类,他的实现类是phoneWindow。
我们一般通过windowManager来访问window。
就是windowmanager和windowmanagerservice的交互。
此外android中你所有能看到的视图,activity,dialog,toast等都是附加在window上的。
window就是view的直接管理者。
2.如何使用windowmanager添加一个view?
答:
1Buttonbt=newButton(this);
2bt.setText("buttonhere");
3WindowManager.LayoutParamslayoutParams=newWindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.WRAP_CONTENT,
40,0,PixelFormat.TRANSPARENT);
5layoutParams.flags=WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
6layoutParams.x=300;
7layoutParams.y=300;
8layoutParams.gravity=Gravity.RIGHT|Gravity.TOP;
9getWindowManager().addView(bt,layoutParams);
ViewCode
3.总共有几种window类型?
答:
三种。
应用window,就是activity这种类型。
子window,就是dialog这种,系统类,toast,状态栏就是系统类型window。
每种对对应着层级范围,应用1-99子1000-1999系统2000-2999.层级最大的,就是显示在最顶层的window了。
4.使用系统window需要注意什么?
答:
注意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
20privatefinalArrayList
21privatefinalArrayList
22newArrayList
23privatefinalArraySet
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 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>=0){ 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} ViewCode 6.activity的window是如何创建的? 答: 应用类的window创建过程: 1 2//activity的window创建由activityThread的performLaunchActivity方法开始 3privateActivityperformLaunchActivity(ActivityClientRecordr,IntentcustomIntent){ 4...... 5if(activity! =null){ 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! =0){ 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! =null){ 60if(lastNonConfigurationInstances! =null){ 61mVoiceInteractor=lastNonConfigurationInstances.voiceInteractor; 62}else{ 63mVoiceInteractor=newVoiceInteractor(voiceInteractor,this,this, 64Looper.myLooper()); 65} 66} 67 68mWindow.setWindowManager( 69(WindowManager)context.getSystemService(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android Window9