日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
android的視圖,app視圖

安卓視圖層級(jí)大揭秘

最近接了一個(gè)語音控制的功能,UI上的具體實(shí)現(xiàn)就是在應(yīng)用上遮蓋一個(gè)透明防觸層,在語音狀態(tài)下阻止用戶點(diǎn)擊,但不能影響物理返回鍵的Dialog呼出即控制,同時(shí)對(duì)于非物理返回鍵呼出的Dialog也要阻止操作。功能看起來很繞,我們用一張圖片來具體說明一下。

創(chuàng)新互聯(lián)長(zhǎng)期為數(shù)千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為莫力達(dá)企業(yè)提供專業(yè)的成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站,莫力達(dá)網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

通過圖片不難看出,我們要實(shí)現(xiàn)的語音控制層其實(shí)是介于應(yīng)用視圖與視圖內(nèi)部提示框之上,同時(shí)又在Back返回鍵彈窗之下的一個(gè)層級(jí)。因?yàn)橐恢币詠韺?duì)安卓視圖層級(jí)的探究不是很深入,所以借著做這個(gè)功能對(duì)安卓視圖層級(jí)這一塊的知識(shí)進(jìn)行了一下總結(jié)梳理。

首先讓我們通過一張層級(jí)圖來明確幾個(gè)重要的概念Window,DecorView和mContentParent。

在Android中不管是Activity、Toast、ActionBar還是Dialog,他們的視圖都是附加到Window上,其實(shí)基本上所有的view同時(shí)通過Window來呈現(xiàn)的,因此Window可以理解為是view的承載者和管理者。Window 有三種類型,分別是應(yīng)用 Window、子 Window 和系統(tǒng) Window。應(yīng)用類 Window 對(duì)應(yīng)一個(gè) Acitivity,子 Window 不能單獨(dú)存在,需要依附在特定的父 Window 中,比如常見的一些 Dialog 就是一個(gè)子 Window。系統(tǒng) Window是需要聲明權(quán)限才能創(chuàng)建的 Window,比如 Toast 和系統(tǒng)狀態(tài)欄都是系統(tǒng) Window。

DecorView是Windows中的View的最頂層View。其實(shí)DecorView是FrameLayout的子類,它里面包含了一個(gè)存有ActionBar以及mContentParent的LinearLayout。

mContentParent這個(gè)名字可能會(huì)有些陌生,其實(shí)他就是我們經(jīng)常使用的應(yīng)用根布局,即android.R.id.content。Activity中的setContentView其實(shí)就是通過LayoutInflater將XML布局轉(zhuǎn)換成View并添加到mContentParent中。

每個(gè)Activity都會(huì)持有一個(gè)Window,而在安卓中,Window只有唯一的一個(gè)實(shí)現(xiàn)類PhoneWindow ,所以每個(gè)Activity都會(huì)持有一個(gè)PhoneWindow,在PhoneWindow中會(huì)持有頂層視圖DecorView。那么Activity是怎么建立與PhoneWindow的聯(lián)系的呢,讓我們通過源碼來探究一下:

在Activity的啟動(dòng)過程中會(huì)執(zhí)行ActivityThread的performLaunchActivity方法,其中調(diào)用Activity的attach。在attach()方法中實(shí)例化Activity持有的mWindow。由于 Activity 實(shí)現(xiàn)了 Window 的 Callback 接口,因此當(dāng) Window 接受到外界的狀態(tài)改變時(shí)就會(huì)回調(diào) Activity 的方法。

可以看到,在PhoneWindow里面,出現(xiàn)了成員變量DecorView。而這里,DecorView則是PhoneWindow里面的一個(gè)內(nèi)部類,它是繼承于FrameLayout。

這是我們每次寫Activity都會(huì)調(diào)用的setContentView方法,它的內(nèi)部調(diào)用了getWindow()的setContentView,這個(gè)mWindow就是PhoneWindow。

我們看到在PhoneWindow中有三個(gè)setContentView的重載方法。在setContentView(int layoutResID)中,首先判斷了mContentParent ,如果mContentParent 為空即為第一次調(diào)用的時(shí)候,就執(zhí)行installDecor()方法,創(chuàng)建DecorView,并添加到mContentParent上。如果mContentParent不為空,那么將mContentParent中的view移除。接著通過mLayoutInflater將XML轉(zhuǎn)換為View樹,并且添加至mContentParent視圖中。 添加完成后回調(diào)通知onContentChanged,表示完成界面加載。

首先判斷mDecor是否為空,如果為空則通過generateDecor創(chuàng)建一個(gè)DecorView,緊接著設(shè)置DecorView的獲取焦點(diǎn)能力為FOCUS_AFTER_DESCENDANTS,即先分發(fā)給Child View進(jìn)行處理,如果所有的Child View都沒有處理,則自己再處理。第一次DecorView未加載到mContentParent,所以mContentParent為空,調(diào)用generateLayout將setContentView內(nèi)容添加到mContentParent。

定制過Acitivity的Actionbar或是Fullscreen的同學(xué)一定都知道,requesetFeature方法需要在setContentView之前調(diào)用,這就是原因。setContentView的實(shí)質(zhì)顯示是觸發(fā)了Activity的resume狀態(tài),也就是觸發(fā)了makeVisible方法。

這里將getWindow().getAttributes()作為了LayoutParams,在WindowManager中:

可以看到Activity的窗口類型是TYPE_APPLICATION,這個(gè)TYPE類型決定了在Window層的顯示層級(jí),TYPE類型總覽如下:

Dialog不屬于View,他是應(yīng)用的子window,所以這也是為什么我們通過給mContentParent添加view無法實(shí)現(xiàn)遮擋Dialog的原因。Dialog 中 Window 同樣是通過 PolicyManager 的 makeNewWindow 方法來完成的,普通的 Dialog 必須采用 Activity 的 Context,如果采用 Application 的 Context 就會(huì)報(bào)錯(cuò)。這是因?yàn)闆]有應(yīng)用 token 導(dǎo)致的,而應(yīng)用 token 一般只有 Activity 擁有。常規(guī)Dialog的TYPE為TYPE_APPLICATION_ATTACHED_DIALOG,通過不同的TYPE層級(jí)劃分我們可以找到置于常規(guī)Dialog之上的WindowManager LayoutParams 屬性,例如TYPE_SYSTEM_ALERT與TYPE_TOAST,設(shè)置了這兩個(gè)屬性的布局是可以將常規(guī)Dialog完全遮蓋的。他們的區(qū)別在于一個(gè)是系統(tǒng)級(jí)別的Dialog一個(gè)是Toast,系統(tǒng)Dialog需要申請(qǐng)權(quán)限。所以我們的第一個(gè)方案就是可遮擋的Dialog使用常規(guī)Dialog,語音提示框采用TYPE_SYSTEM_ALERT。但是都知道安卓有一個(gè)無法逃避的問題,就是廠商定制,在MUI的framework層,出于對(duì)“安全”的考慮,默認(rèn)為用戶關(guān)閉了懸浮窗權(quán)限,也就是是說設(shè)置了TYPE_SYSTEM_ALERT屬性的視圖默認(rèn)是無法顯示的,需要用戶手動(dòng)開啟權(quán)限以后方可顯示。

雖然可以在用戶啟動(dòng)的時(shí)候根據(jù)用戶機(jī)型選擇跳轉(zhuǎn)開啟權(quán)限頁,但作為一個(gè)有情懷的開發(fā)這種不完美的體驗(yàn)還是不能接受的。根據(jù)之前對(duì)安卓視圖層級(jí)的學(xué)習(xí),我們有了第二套方案。應(yīng)用視圖是存放于mContentParent他與Activity同屬TYPE_APPLICATION Window層級(jí)屬于最下層,常規(guī)Dialog的層級(jí)是TYPE_APPLICATION_ATTACHED_DIALOG,所以我們將常規(guī)Dialog作為最上層不可遮擋的提示框,下面只需考慮可遮擋的彈窗與語音控制兩層即可。因?yàn)檎Z音控制層需要能夠遮擋提示彈窗,所以需要語音控制層在彈窗的上層,經(jīng)過之前的學(xué)習(xí),我們把彈窗加入到mContentParent,把語音控制層添加到DecorView層即可完美的解決問題。mContentParent為一個(gè)FrameLayout,應(yīng)用視圖通過sentContentView率先添加到mContentParent中,作為提示彈窗,添加順序一定相對(duì)應(yīng)用視圖置后,所以當(dāng)提示彈窗再次向mContentParent添加的時(shí)候,即會(huì)添加到應(yīng)用視圖之上。而DecorView是mContentParent的父容器,也是一個(gè)FrameLayout,添加語音提示框的時(shí)候mContentParent一定已經(jīng)存在,所以添加的時(shí)候一定會(huì)在mContentParent之上。

就這樣,一個(gè)看似復(fù)雜的需求通過對(duì)安卓源碼的探究完美的解決了,很多時(shí)候當(dāng)我們遇到難以解決的問題,不妨試試回到問題的原點(diǎn),思考一下問題的本質(zhì),很多時(shí)候都會(huì)有不一樣的發(fā)現(xiàn)。

Android app視圖查看工具

由于android提供的uiautomatorviewer有許多信息我們無法看到,比如控件的id和類名,這些都是我們用來分析的重要因素。所以利用業(yè)余的時(shí)間我做了一個(gè)手機(jī)App視圖查看工具,利用的是python的PyQt和Android注入去實(shí)現(xiàn)的,源碼都在我的Git上。

注入項(xiàng)目:

python Windows界面:

安卓開發(fā)之在當(dāng)前Activity獲取視圖View

一般來說,獲取當(dāng)前活動(dòng)中的某一個(gè)視圖還是很方便的,我們?cè)谑褂胦nClick函數(shù)的時(shí)候經(jīng)常會(huì)見到這樣的用法:

我們注意到,make函數(shù)的第一個(gè)參數(shù)是v,這可以是當(dāng)前布局的任意一個(gè)View,Snackbar會(huì)使用這個(gè)View來找到最外層的布局從而展示Snackbar。但是我們有的時(shí)候并不是使用onClick函數(shù)來調(diào)用Snackbar。例如我們會(huì)在onOptionsItemSelected函數(shù)中使用Snackbar。此時(shí),我們可以借用下列方法獲取View視圖:

getWindow().getDecorView().findViewById(Android.R.id.content)

就上述例子來說,可以修改為這樣:

就是這樣啦,蟹蟹大家的閱讀!

android 視圖變黑

1、解決android視圖變黑問題的最簡(jiǎn)單方法是可以通過同時(shí)按住“主頁”和“電源”按鈕10秒鐘,然后釋放兩個(gè)按鈕并按住“電源”按鈕直到屏幕打開來硬重啟android設(shè)備。

2、也可以等待android在電池耗盡時(shí)自動(dòng)關(guān)閉。然后為android充電,然后按“電源”按鈕將其打開。

Android進(jìn)階 - 視圖層級(jí)實(shí)時(shí)分析

在App運(yùn)行過程中,我們的視圖層級(jí)可能會(huì)由于用戶的操作一直在發(fā)生改變,甚至可能會(huì)有一些出乎預(yù)料的變化,本文將會(huì)介紹 如何進(jìn)行Android視圖實(shí)時(shí)分析,分析View的視圖層級(jí)及屬性變化。

首先,筆者先來一個(gè)簡(jiǎn)單的Demo實(shí)例。我們使用Android Studio新建一個(gè)Empty Android工程,跑一下程序,界面如下圖所示:

接下來,我們要對(duì)視圖層級(jí)進(jìn)行分析,但分析之前先給各位介紹兩個(gè)視圖分析工具。

1. Android SDK 中 tools 包下的 hierarchyviewer ,最終展現(xiàn)的視圖效果如下:

2. Android Studio 也有自帶的視圖分析工具 Layout Inspector(布局檢查器) ,打開方式如下圖所示:

可以看到Layout Inspector最右側(cè)的屬性欄可以查看 每一個(gè)View的所附帶的屬性及屬性值 。

從根視圖開始分析視圖層級(jí),如下圖所示:

DecorView的第一個(gè)子View(LinearLayout), 如下圖所示:

DecorView的第二個(gè)子View(View),如下圖所示:

DecorView的第三個(gè)子View(View),如下圖所示:

至此,DecorView的最外層View全部分析完畢。

接下來,分析DecorView的第一個(gè)子View(LinearLayout),如下圖所示:

ViewStub的屬性信息,如下圖所示:

FrameLayout的屬性信息,如下圖所示:

接下來,繼續(xù)分析FrameLayout的子View,如下圖所示:

ContentFrameLayout的視圖屬性,如下圖所示:

ActionBarContainer的視圖屬性,如下圖所示:

不過,還有個(gè)問題需要提醒一下, 不同機(jī)型,不同系統(tǒng)主題設(shè)置 生成的視圖結(jié)構(gòu)可能會(huì)不一樣,舉兩個(gè)例子:

例一:筆者把使用的模擬器換成自己的手機(jī)(360N5 Android 6.0.1) ,運(yùn)行后視圖布局如下:

可以看到 筆者的手機(jī)是沒有NavigationBar(底部導(dǎo)航欄)的 。

例二:筆者把Activity的主題"Theme.AppCompat.Light.DarkActionBar"換成無標(biāo)題欄主題"Theme.AppCompat.Light.NoActionBar" ,運(yùn)行后視圖布局如下:

可以看到視圖結(jié)構(gòu)與我們之前分析的相比,發(fā)生了一些變化。

最后,還有個(gè)細(xì)節(jié)給各位補(bǔ)充下: Layout Inspector 只能分析出Android Studio當(dāng)前 “正在運(yùn)行的APP” 的視圖布局結(jié)構(gòu),其他應(yīng)用的視圖布局結(jié)構(gòu)是無法顯示的。

如果我們想要分析一個(gè)第三方應(yīng)用(如:微信、QQ)的視圖結(jié)構(gòu)可以使用 Android Device Monitor(安卓設(shè)備監(jiān)視器) ,具體打開步驟如下圖所示:

以QQ為例,我們先打開手機(jī)QQ,顯示出QQ主界面,然后按照下圖的 "紅色圈選" ,依次點(diǎn)擊,當(dāng)前的視圖結(jié)構(gòu)就出來了,但是相比于 Layout Inspector 工具,視圖屬性信息提供的較少...

視圖層級(jí)分析 到此結(jié)束,有時(shí)間再補(bǔ)篇源碼,分析一下布局加載的流程。

寫這篇文章的時(shí)候被IOS同事嘲諷了,它們吐槽Android的視圖分析工具太渣,最后對(duì)比看了下,Android的視圖分析工具確實(shí)沒有IOS的高大上......╮(╯▽╰)╭

最后,秀一下IOS的視圖分析工具 Reveal ,如下圖所示:

Android自定義視圖清空畫布

執(zhí)行方法:

默認(rèn)情況下,視圖會(huì)在onDraw前會(huì)清空畫布內(nèi)容,詳細(xì)見ViewRootImpl中的drawSoftware方法:

但是如果在其他位置或使用其他方式獲取Canvas時(shí)可能導(dǎo)致之前的內(nèi)容還留在畫布上,例如:

此時(shí)在繪制新的內(nèi)容前需要先清空畫布。

2020-11-16


本文題目:android的視圖,app視圖
轉(zhuǎn)載來于:http://www.dlmjj.cn/article/hoohjj.html