亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android?資源加載使用偽代碼示例分析

 更新時間:2022年10月12日 09:36:51   作者:Petterp  
這篇文章主要為大家介紹了Android?資源加載使用偽代碼示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

聊到 Android 的 資源加載 ,每一個開發(fā)同學都會非常熟悉,畢竟從使用來說,我們日常都會見到,比如 getText() 等等。

那如果此時問你,你知道 它們到底是怎么被加載的,內部會有什么處理嗎?

為什么同一個drawable界面更改了透明度,其他界面也會生效?

如果你對上述問題依然存疑,那本文可能會對你有所幫助。

介于此,本篇將由淺入深,從源頭理清 Resource.getx() 的那些事,從而為理解 Android資源加載 邁出第一步。故此名: 小試牛刀。

本篇定位中等??,主要通過偽源碼分析的形式,從而探索應用層 Resource.getx 的實現(xiàn)細節(jié)。

Resource是什么?

Resource,在 Android 中,指的是我們開發(fā)中使用到的資源,例如 drawable、String、anim、color 等。其會在開發(fā)階段生成相應的R類以及對應的 資源ID ,以便開發(fā)者在使用時通過傳遞 資源Id ,從而獲取相應類型的資源文件。

比如我們在 Activity,Fragment 中經(jīng)常使用的 getString() , getDrawable() ,內部也都是調用的 resource.getxx 實現(xiàn)。

常見也有 ContextCompat.getDrawable() ,那它與直接調用resource.getDrawable()有什么區(qū)別?

見名知意,其主要是作為兼容使用,目的是解決不同版本之間的差異。

基礎概念

TypedValue

用于保存數(shù)據(jù)的動態(tài)容器,主要用于配合 Resource 保存資源。

具體而言,當我們獲取資源時,底層會調用相應的原生方法將讀取到的資源信息寫入其中,以便后續(xù)的判斷與使用;

AssetsManager

資源管理器,用于讀取打包到 Apk 內部的資源文件。

具體而言,當我們調用 getxxx 時,其最終會去調用相應的原生方法獲取資源信息并寫入 TypedValue

ResourcesImpl

Resource 的具體實現(xiàn)類,我們調用的相關 getxxx 方法,最終都是其作為具體實現(xiàn),內部最終會調用 AssetsManager 進行加載資源,并且會處理與之關聯(lián)的所有緩存。

getText

getText(R.string.xx)

用于從資源文件中獲取文本,具體源碼如下:

從源碼中看,我們調用的 getText() 最終實際調用了 ResourcesImpl , 內部會使用 AssetsManager 去從底層獲取相應的文本資源,并將其保存到 TypedValue 中。如果此次獲取的文本資源是字符串類型,則直接從字符串常量池中去取,否則將取到的文本資源轉為字符串后返回。

getDrawable

getDrawable(R.drawable.xxx)

用于從資源文件中獲取可繪制對象,具體偽源碼如下:

當我們調用 getDrawable() 時,內部先會通過 getValueForDensity() 獲取當前密度下相應的資源文件,并將其寫入到 TypeValue 中;

如果不存在資源文件,則直接拋出異常。然后通過 ResourcesImpl.loadDrawable 去加載 Drawable。

繼續(xù)沿著剛才的源碼,我們去看看 loadDrawable 內部到底做了什么,偽代碼如下:

這個方法流程較長,我們將其分為下面幾個步驟:

  • 判斷當前要加載的 drawable 是否具有緩存;
  • 判斷當前 drawable 是否為顏色drawable;
  • 如果當前沒有加載 drawable &&當前drawable 已緩存 ,直接返回該drawable;
  • 從當前緩存中取出當前 drawable 對應的 狀態(tài)與數(shù)據(jù)參數(shù)(如果存在緩存) ;

創(chuàng)建新的 drawable 。如果當前存在緩存,則利用緩存的狀態(tài)(Drawable.ConstantState) 構建 Drawable,否則如果是顏色drawable,則直接創(chuàng)建;否則調用 從xml或者資源中加載drawable,具體偽代碼如下圖:

  • 處理構建的drawable 主題與參數(shù) ;
  • 如果當前drawable 沒有緩存 ,則將添加到緩存中。

小結

當我們調用 getDrawable() 時,內部會先判斷當前資源是否存在,如果不存在則直接拋出異常;接著調用 ResourcesImpl.loadDrawable 去加載具體的 drawable ,內部會根據(jù)要加載的 drawable類型、是否是Color,以及是否存在緩存綜合獲取,如果存在當前屏幕密度的drawable,則使用緩存,否則重新加載。然后根據(jù)要加載的 drawable 文件后綴 決定是 colorDrawable 還是 BitMapDrawable ,或者是其他類型的Drawable,最后將加載完成的 Drawable狀態(tài)與配置參數(shù)(ConstantState) 加入到 緩存 中。

Tips

知道了 Drawable 會被緩存的知識點,此時就不難解釋為什么開發(fā)中會遇到同一個 Drawable 更改了透明度,其他界面用到這個 Drawable 的地方也會受到了影響。

如下示例:

解決辦法就是,在 drawable 更改透明度時,調用 mutate() 即可,原理上也很簡單,重新new了一個狀態(tài):

background.mutate().alpha = 100
復制代碼

例如:

getColor

getColor(R.color.xxx)

用于獲取相應 資源id 關聯(lián)的顏色,具體的源碼如下:

當我們調用 getColor() 時,內部先會通過 getValue() 獲取相應的 color 資源,并將其保存到 TypeValue 中;如果不存在資源文件,則直接拋出異常。然后通過 ResourcesImpl.loadColorStateList() 去加載,最后返回顏色狀態(tài)列表的 默認顯示顏色

我們繼續(xù)向下看: loadColorStateList()

當調用 loadColorStateList 加載顏色狀態(tài)合集時,內部有兩個分支:

  • 如果當前要獲取的顏色類型是 “#xxx” ,則先從預加載數(shù)組中取,如果此時沒有加載,則創(chuàng)新的 ColorStateList ,并將其存到預加載數(shù)組中;
  • 如果當前要獲取的顏色類型是引用類型,則意味著當前可能要從xml中去取。內部先從緩存數(shù)組中去,如果不存在則再去預加載數(shù)組中取,如果依然不存在,則調用 loadComplexColorForCookie() 重新初始化。當加載完成后,如果此時正在預加載,將其添加到預加載數(shù)組中,否則將其添加到緩存里。

接著上面的末梢,我們最后再去看一下 loadComplexColorForCookie() ,也即一個全新的color到底是如何從xml中拿到

該方法里,先判斷資源文件的后綴名,如果非 .xml 類型,則該資源無法讀取,直接拋出異常;否則先調用 loadXmlResourceParser() 拿到該資源文件的 xml解析器 ,再由解析器的 name 判斷具體的資源類型,從而初始化具體的顏色類。

總結

當我們調用 getColor() 獲取某個顏色資源時,內部會先通過 AssetsManager 加載該資源,并將其保存到 TypedValue 中,如果沒有讀到,則拋出異常;否則調用 ResoucesImpl.loadColorStateList() 獲取顏色資源,如果該資源在緩存中存在,則直接取出并返回新的實例,否則根據(jù)當前要加載的類型,如果是 “#xxx” ,則直接初始化并添加到緩存,否則判斷 TypedValue 中保存的資源信息 后綴 是否為 xml ,如果不是則直接拋出異常,證明此時非 .xml 文件,文件無法讀取,否則通過 AssetManager 獲取該資源對應的 xml解析器 ,并判斷解析器的名字,從而決定創(chuàng)建 GradientColor 還是 ColorStateList,然后將結果緩存到 ResourcesImpl 中并返回。

關于 Resource.getx() 相關的底層實現(xiàn)到這里就分析結束了。本篇中,我們以 Kotlin+[裁枝剪葉] 的方式,提供一個較清晰的脈絡,以供更好的讀懂應用層源碼設計,關于更細節(jié)的原生實現(xiàn),并不是本篇所關注的。所謂一眼入森,而不在林,正是如此。

現(xiàn)在讓我們反推上去:

原來我們每次調用 getDrawable() 時,內部都是做了緩存處理(緩存了ConstantState),原來我們獲取的 drawable,無非就三種大的類型:

  • .xml 結尾的,ColorDrawable 或者 非ColorDrawable;
  • 非.xml 結尾的,即為 BitmapDrawable。

那他們又是怎么判斷得出的呢?通過 AssetManager 獲取,將其保存到 TypedValue 中,使用時通過判斷 資源文件名后綴 而定。又因為drawable 存在 緩存狀態(tài)復用 ,所以又會導致 一處更新,處處同步 問題。原來 getColor() 內部同樣做了緩存處理等。

至此,關于 Android-Resource 的求知篇正式開始,下一篇我將同大家分析 Resource 的初始化時機以及與 Resource.system() 的區(qū)別。

更多關于Android 資源加載的資料請關注腳本之家其它相關文章!

相關文章

  • Android5.0以上實現(xiàn)全透明的狀態(tài)欄方法(仿網(wǎng)易云界面)

    Android5.0以上實現(xiàn)全透明的狀態(tài)欄方法(仿網(wǎng)易云界面)

    下面小編就為大家分享一篇Android5.0以上實現(xiàn)全透明的狀態(tài)欄方法(仿網(wǎng)易云界面),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • Android抓取CSDN首頁極客頭條內容完整實例

    Android抓取CSDN首頁極客頭條內容完整實例

    這篇文章主要介紹了Android抓取CSDN首頁極客頭條內容完整實例,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • Android自定義圖片集合

    Android自定義圖片集合

    這篇文章主要為大家分享了內容相當豐富的Android自定義圖片集合,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-02-02
  • Android實現(xiàn)音樂播放器歌詞顯示效果

    Android實現(xiàn)音樂播放器歌詞顯示效果

    這篇文章主要為大家詳細介紹了Android實現(xiàn)音樂播放器歌詞顯示效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • Android SwipeRefreshLayout超詳細講解

    Android SwipeRefreshLayout超詳細講解

    在android開發(fā)中,使用最多的數(shù)據(jù)刷新方式就是下拉刷新了,而完成此功能我們使用最多的就是第三方的開源庫PullToRefresh?,F(xiàn)如今,google也忍不住推出了自己的下拉組件SwipeRefreshLayout,下面我們通過api文檔和源碼來分析學習如何使用SwipeRefreshLayout
    2022-11-11
  • Android布局之LinearLayout線性布局

    Android布局之LinearLayout線性布局

    LinearLayout是線性布局控件:要么橫向排布,要么豎向排布,下面通過本篇文章給大家介紹Android布局之LinearLayout線性布局,涉及到android linearlayout 布局相關知識,對本文感興趣的朋友一起學習吧
    2015-12-12
  • Android自定義控件之開關按鈕學習筆記分享

    Android自定義控件之開關按鈕學習筆記分享

    這篇文章主要為大家分享了Android自定義開關按鈕的學習筆記,內容豐富,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-05-05
  • android實現(xiàn)百度地圖自定義彈出窗口功能

    android實現(xiàn)百度地圖自定義彈出窗口功能

    這篇文章主要介紹了android實現(xiàn)百度地圖自定義彈出窗口的功能,大家參考使用吧
    2013-11-11
  • Android進階教程之ViewGroup自定義布局

    Android進階教程之ViewGroup自定義布局

    這篇文章主要給大家介紹了關于Android進階教程之ViewGroup自定義布局的相關資料,文中通過示例代碼介紹的非常詳細,對各位Android開發(fā)者們具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-06-06
  • 利用Kotlin實現(xiàn)破解Android版的微信小游戲--跳一跳

    利用Kotlin實現(xiàn)破解Android版的微信小游戲--跳一跳

    這篇文章主要給大家介紹了關于利用Kotlin實現(xiàn)破解Android版微信小游戲--跳一跳的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2017-12-12

最新評論