Android中Window9问9答.docx

上传人:b****3 文档编号:3884173 上传时间:2022-11-26 格式:DOCX 页数:17 大小:24.90KB
下载 相关 举报
Android中Window9问9答.docx_第1页
第1页 / 共17页
Android中Window9问9答.docx_第2页
第2页 / 共17页
Android中Window9问9答.docx_第3页
第3页 / 共17页
Android中Window9问9答.docx_第4页
第4页 / 共17页
Android中Window9问9答.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

Android中Window9问9答.docx

《Android中Window9问9答.docx》由会员分享,可在线阅读,更多相关《Android中Window9问9答.docx(17页珍藏版)》请在冰豆网上搜索。

Android中Window9问9答.docx

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

19privatefinalArrayListmViews=newArrayList();

20privatefinalArrayListmRoots=newArrayList();

21privatefinalArrayListmParams=

22newArrayList();

23privatefinalArraySetmDyingViews=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

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(

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1