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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Android 浮窗开发之窗口层级

發布時間:2023/12/19 综合教程 26 生活家
生活随笔 收集整理的這篇文章主要介紹了 Android 浮窗开发之窗口层级 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

很多人都知道如何去實現一個簡單的浮窗,但是卻很少有人去深入的研究背后的流程機制,由于項目中浮窗交互比較復雜,遇到了些坑查看了很多資料,故總結浮窗涉及到的知識點:

窗口層級關系(浮窗是如何“浮”的)?
浮窗有哪些限制,如何越過用戶授權實現浮窗功能?
窗口與用戶輸入系統(Activity是如何接收到touch事件?)。

本章我們來研究第一個問題:浮窗為何會浮。 浮窗之所以叫浮窗,是因為它能懸浮于應用或者桌面窗口之上,能脫離Activity而存在。為了研究其中區別,我們先來看看我們最熟悉的Activity是怎么顯示出來的。

Activity是怎么顯示出來的?

要弄清這個問題答案,我們先從Activity的setContentView()這個方法的源碼開始找起,在Activity中看到setCententView的源碼:

public void setContentView(int layoutResID) {
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    }

getWindow是返回返回Activity的mWindow變量,指向一個Window的對象,Window是一個抽象類,這里返回的是PhoneWindow對象(PhoneWindow是Window的子類),PhoneWindow中有一個DecorView對象,decorView成員,這是一個FrameLayout,setContentView的子布局最終會添加到decorView中,這個decorView就是當前窗口的根視圖,這個根視圖是如何最終被繪制出來的?在ActivityThread中有這樣一段代碼:

l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (a.mVisibleFromClient) {
                    a.mWindowAdded = true;
                    wm.addView(decor, l);
                }

這個decorView,最終會被WindowManager.addView添加到繪制系統中,并類型是WindowManager.LayoutParams.TYPE_BASE_APPLICATION,這個參數決定了要繪制的窗口的z軸層次,為了避免思維棧過深,這里就不貼出詳細的源碼跟蹤過程了,直接給結論。

先來看看Activity和window的關系:

再來window和View的關系:

Activity窗口顯示過程:

說Activity是怎么顯示出來的,其實是說Activity管理的View是怎么顯示出來的。最后再來總結一下:

一、Activity通過setContentView設置的視圖是添加到PhoneWindow的根視圖decor中。

二、Window是一個抽象的概念,Window關了了一個View(根視圖),最終被WindowManager管理的還是一個View(根視圖)和它的LayoutParams,視圖繪制刷新都是通過WindowManager(WindowManagerGlobal)與WindowManagerServiceIPC交互調用底層繪制的。

三、Activity是四大組件中唯一和窗體緊密聯系的組件(這是為什么會有初學者把Activity直接理解為繪制界面的原因),所有掌管的視圖只不過是一種window和Dialog、Toast、墻紙所掌管的Window類型不一樣。

浮窗為什么會“浮”?

上面講到Activity的顯示過程其實已經揭示了通用界面的顯示過程,浮窗的顯示過程更為簡單:

做過浮窗的同學應該都明白了,為啥浮窗能脫離Activity而顯示,本質上我們是把一個View交給WindowManager來管理了,LayoutParams.type類型決定了這個View顯示窗口的類型,不同類型顯示的窗口層次(z軸)是不一樣的。大方面來講可以分為應用窗口(APPLICATION_WINDOW)、子窗口(SUB_WINDOW)、系統窗口(SYSTEM_WINDOW)三種類型,應用窗口z軸范圍是1~99,子窗口的范圍是1001~1999,系統窗口是(2000~2999),所以要實現浮動窗口我們只能在系統窗口范圍中實現。

類型 常量范圍 子類 常量值 說明 例子
APPLICATION_WINDOW 1~99 TYPE_BASE_APPLICATION 1
TYPE_APPLICATION 2 應用窗口 大部分的應用程序窗口
TYPE_APPLICATION_STARTING 3 應用程序的Activity顯示之前由系統顯示的窗口
LAST_APPLICATION_WINDOW 99
SUB_WINDOW 1000~1999 FIRST_SUB_WINDOW 1000
TYPE_APPLICATION_PANEL 1000 顯示在母窗口之上,遮擋其下面的應用窗口。
TYPE_APPLICATION_MEDIA 1001 顯示在母窗口之下,如果應用窗口不挖洞,即不可見。 SurfaceView,在小窗口顯示時設為MEDIA, 全屏顯示時設為PANEL
TYPE_APPLICATION_SUB_PANEL 1002
TYPE_APPLICATION_ATTACHED_DIALOG 1003
TYPE_APPLICATION_MEIDA_OVERLAY 1004 用于兩個SurfaceView的合成,如果設為MEDIA,則上面的SurfaceView 擋住下面的SurfaceView
SYSTEM_WINDOW 2000~2999 TYPE_STATUS_BAR 2000 頂部的狀態欄
TYPE_SEARCH_BAR 2001 搜索窗口,系統中只能有一個搜索窗口
TYPE_PHONE 2002 電話窗口
TYPE_SYSTEM_ALERT 2003 警告窗口,在所有其他窗口之上顯示 電量不足提醒窗口
TYPE_KEYGUARD 2004 鎖屏界面
TYPE_TOAST 2005 短時的文字提醒小窗口
TYPE_SYSTEM_OVERLAY 2006 沒有焦點的浮動窗口
TYPE_PRIORITY_PHONE 2007 緊急電話窗口,可以顯示在屏保之上
TYPE_SYSTEM_DIALOG 2008 系統信息彈出窗口 比如SIM插上后彈出的運營商信息窗口
TYPE_KEYGUARD_DIALOG 2009 跟KeyGuard綁定的彈出對話框 鎖屏時的滑動解鎖窗口
TYPE_SYSTEM_ERROR 2010 系統錯誤提示窗口 ANR 窗口
TYPE_INPUT_METHOD 2011 輸入法窗口,會擠占當前應用的空間
TYPE_INPUT_METHOD_DIALOG 2012 彈出的輸入法窗口,不會擠占當前應用窗口空間,在其之上顯示
TYPE_WALLPAPER 2013 墻紙
TYPE_STATUS_BAR_PANEL 2014 從狀態條下拉的窗口
TYPE_SECURE_SYSTEM_OVERLAY 2015 只有系統用戶可以創建的OVERLAY窗口
TYPE_DRAG 2016 浮動的可拖動窗口 360安全衛士的浮動精靈
TYPE_STATUS_BAR_PANEL 2017
TYPE_POINTER 2018 光標
TYPE_NAVIGATION_BAR 2019
TYPE_VOLUME_OVERLAY 2020 音量調節窗口
TYPE_BOOT_PROGRESS 2021 啟動進度,在所有窗口之上
TYPE_HIDDEN_NAV_CONSUMER 2022 隱藏的導航欄
TYPE_DREAM 2023 屏保動畫
TYPE_NAVIGATION_BAR_PANEL 2024 Navigation bar 彈出的窗口 比如說應用收集欄
TYPE_UNIVERSAL_BACKGROUND 2025
TYPE_DISPLAY_OVERLAY 2026 用于模擬第二顯示設備
TYPE_MAGNIFICATION 2027 用于放大局部
TYPE_RECENTS_OVERLAY 2028 當前應用窗口,多用戶情況下只顯示在用戶節目

總結

以上是生活随笔為你收集整理的Android 浮窗开发之窗口层级的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。