日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

[转]Android 之 Window、WindowManager 与窗口管理

發(fā)布時間:2025/3/8 Android 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转]Android 之 Window、WindowManager 与窗口管理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

這篇是對前兩天研究的懸浮窗的內(nèi)容的一個小小的資料整理吧。首先是轉(zhuǎn)載一篇介紹Android窗口的內(nèi)容,覺得寫得不錯:http://blog.csdn.net/xieqibao/article/details/6567814

為防止丟失還是把內(nèi)容也拷一遍吧(*^__^*) 嘻嘻……

其實在android中真正展示給用戶的是window和view,activity在android中所其的作用主要是處理一些邏輯問題,比如生命周期的管理、建立窗口等。在android中,窗口的管理還是比較重要的一塊,因為他直接負責把內(nèi)容展示給用戶,并和用戶進行交互。響應(yīng)用戶的輸入等。

在講窗口管理時,有必要先說下ViewManager這個接口,這個接口主要有以下的實現(xiàn)子接口和實現(xiàn)類,分別是:WindowManager和ViewGroup里面還有三個重要的方法:

  • addView();?
  • updateViewLayout();
  • removeView();

在WindowManager中,addView方法表示的是將主窗口中的頂級view(也就是DecorView)添加到WindowManager中,并建立會話。接下來會詳細介紹。我們先來看看Window

Window:

Windowandroid中的窗口,表示頂級窗口的意思,也就是主窗口,它有兩個實現(xiàn)類,PhoneWindowMidWindow,我們一般的activity對應(yīng)的主要是PhoneWindow,在activity中經(jīng)常使用的setContentView等方法也是在這個里面實現(xiàn)的。

1 @Override 2 public void setContentView(View view,ViewGroup.LayoutParams params) 3 { 4 if (mContentParent == null) 5 { 6 installDecor(); 7 } 8 else 9 { 10 mContentParent.removeAllViews(); 11 } 12 mContentParent.addView(view, params); 13 final Callback cb = getCallback(); 14 if (cb != null) 15 { 16 cb.onContentChanged(); //窗口類容發(fā)生變化時更新 17 } 18 } View Code

?每個主窗口中都有一個View,稱之為DecorView,是主窗口中的頂級view(實際上就是ViewGroup),在View中有兩個成員變量叫做mParent、mChildren,它是用來管理view的上下級關(guān)系的。而ViewGroup是對一組View的管理。因此,在ViewGroup中建立了所有view的關(guān)系網(wǎng)。而最終ViewGroup附屬在主窗口上。這樣就很容易在窗口中通過findViewById找到具體的View了。view中的事件處理也是根據(jù)這個路徑來處理的。

我們再來看看ActivityThead中的兩個重要的方法(至于ActivityThead將在一篇中詳細介紹):

  • performLaunchActivity( );
  • handleResumeActivity( );

在performLaunchActivity中,會調(diào)用activity.attach方法建立一個window,?在handleResumeActivity方法中啟動activity的時候,會將主窗口加入到WindowManager中

1 View decor =r.window.getDecorView(); //獲得窗口的頂級View 2 decor.setVisibility(View.INVISIBLE); 3 ViewManager wm= a.getWindowManager(); //WindowManager繼承自ViewManager 4 WindowManager.LayoutParams l= r.window.getAttributes(); 5 6 a.mDecor = decor; 7 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 8 l.softInputMode |= forwardBit; 9 10 if (a.mVisibleFromClient) 11 { 12 a.mWindowAdded = true; 13 wm.addView(decor, l); //實際上是把主窗口的頂級view加入到WindowMangaer 14 } View Code

我們再來看看WindowManager。

WindowManager:

WindowManager主要用來管理窗口的一些狀態(tài)、屬性、view增加、刪除、更新、窗口順序、消息收集和處理等。

通過Context.getSystemService(Context.WINDOW_SERVICE)的方式可以獲得WindowManager的實例.

WindowManager繼承自ViewManager,里面涉及到窗口管理的三個重要方法,分別是:

  • addView();?
  • updateViewLayout();
  • removeView();??

WindowManager中還有一個重要的靜態(tài)類LayoutParams.通過它可以設(shè)置和獲得當前窗口的一些屬性。

我們先來看看addView()方法,在addView中,會利用LayoutParams獲得window的View屬性,并為每個window創(chuàng)建ViewRoot,ViewRoot是View和WindowManager之間的橋梁,真正把View傳遞給WindowManager的是通過ViewRoot的setView()方法,ViewRoot實現(xiàn)了View和WindowManager之間的消息傳遞。在將主窗口添加到WindowManger時,它首先會建立一個代理對象:

??????????????wm=(WindowManagerImpl)context.getSystemService(Context.WINDOW_SERVICE)

并且打開會話(IWindowSession),之后Window將通過該會話與WindowManager建立聯(lián)系,

來看下setView方法:

1 try 2 { 3 res =sWindowSession.add(mWindow, mWindowAttributes, 4 getHostVisibility(), mAttachInfo.mContentInsets); 5 } 6 catch (RemoteException e) 7 { 8 mAdded = false; 9 mView = null; 10 mAttachInfo.mRootView =null; 11 unscheduleTraversals(); 12 throw newRuntimeException("Adding window failed", e); 13 } 14 finally 15 { 16 if (restore) 17 { 18 attrs.restore(); 19 } 20 } View Code

在這段代碼中,ViewRoot通過IWindowSession把窗口添加到WindowManager中。ViewRoot繼承了Handler,實際上它的本質(zhì)就是一個Handler,窗口中View的事件處理、消息發(fā)送、回調(diào)等將通過ViewRoot來處理。

這樣就完成了把窗口添加到WindowManager中,并交由WindowManager來管理窗口的view、事件、消息收集處理等。

?

知道原理之后添加懸浮窗的工作就比較簡單了,主要關(guān)鍵點有以下幾個:

1. 首先是AndroidManifest.xml文件中添加權(quán)限<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

2. 獲取WindowManager窗口mWindowManager?=?(WindowManager)getApplication().getSystemService(getApplication().WINDOW_SERVICE);

3. 設(shè)置窗口屬性:

1 //設(shè)置window type 2 wmParams.type = LayoutParams.TYPE_PHONE; 3 //設(shè)置圖片格式,效果為背景透明 4 wmParams.format = PixelFormat.RGBA_8888; 5 //設(shè)置浮動窗口不可聚焦(實現(xiàn)操作除浮動窗口外的其他可見窗口的操作) 6 wmParams.flags = LayoutParams.FLAG_NOT_FOCUSABLE; 7 //調(diào)整懸浮窗顯示的停靠位置為左側(cè)置頂 8 wmParams.gravity = Gravity.LEFT | Gravity.TOP; 9 // 以屏幕左上角為原點,設(shè)置x、y初始值,相對于gravity 10 wmParams.x = 0; 11 wmParams.y = 0; 12 13 //設(shè)置懸浮窗口長寬數(shù)據(jù) 14 wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT; 15 wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT; 16 17 /*// 設(shè)置懸浮窗口長寬數(shù)據(jù) 18 wmParams.width = 200; 19 wmParams.height = 80;*/ 20 21 LayoutInflater inflater = LayoutInflater.from(getApplication()); 22 //獲取浮動窗口視圖所在布局 23 mFloatLayout = (LinearLayout) inflater.inflate(R.layout.float_layout, null); 24 //添加mFloatLayout 25 mWindowManager.addView(mFloatLayout, wmParams); View Code

轉(zhuǎn)載于:https://www.cnblogs.com/Pitty/articles/3861211.html

總結(jié)

以上是生活随笔為你收集整理的[转]Android 之 Window、WindowManager 与窗口管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。