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

Android性能優(yōu)化系列篇UI優(yōu)化

 更新時(shí)間:2022年10月14日 08:47:51   作者:塞爾維亞大漢  
這篇文章主要為大家介紹了Android性能優(yōu)化系列篇UI優(yōu)化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

從網(wǎng)上匯總搜集眾多大佬的性能優(yōu)化文章,整理出來(lái)部分知識(shí)點(diǎn),主要包含:

UI優(yōu)化/啟動(dòng)優(yōu)化/崩潰優(yōu)化/卡頓優(yōu)化/安全性?xún)?yōu)化/弱網(wǎng)優(yōu)化/APP深度優(yōu)化等等等~

本篇是第一篇:UI優(yōu)化!  [非商業(yè)用途,如有侵權(quán),請(qǐng)告知我,我會(huì)刪除]

一、UI優(yōu)化

UI優(yōu)化知識(shí)點(diǎn)主要分為三部分:

  • 第一部分,系統(tǒng)為我們做的優(yōu)化。由于前端中UI展示的特殊性和重要性,Android團(tuán)隊(duì)也是在不斷想辦法提高UI方面的渲染速度,所以也是更新了很多系統(tǒng)優(yōu)化方案,比如:

硬件加速、黃油計(jì)劃、RenderThread。

  • 第二部分,我們可以具體實(shí)施的優(yōu)化方案。主要包括:

java代碼布局、View重用、異步創(chuàng)建View、xml布局優(yōu)化、異步布局框架Litho、屏幕適配、Flutter、Jetpack Compose

  • 第三部分,工具使用,主要包括:

Choreographer、monitor、Systrace

1.1 系統(tǒng)做的優(yōu)化

1.1.1 硬件加速

之前我們說(shuō)過(guò),一個(gè)圖形的繪制是CPU,GPU和屏幕三方合作的結(jié)果。

Android3.0之前,還沒(méi)有硬件加速,都是通過(guò)CPU進(jìn)行數(shù)據(jù)計(jì)算,然后通過(guò)Skia庫(kù)進(jìn)行軟件繪制,但是CPU對(duì)于圖形處理并不高效。

于是從3.0開(kāi)始,Android支持了硬件加速,到Android4.0默認(rèn)開(kāi)啟硬件加速。

開(kāi)啟硬件加速后,就是由CPU進(jìn)行圖形緩存數(shù)據(jù)的繪制。這樣CPU和GPU就能比較好的分工,各司其職了。CPU用于控制復(fù)雜繪制邏輯、構(gòu)建或更新DisplayList(基礎(chǔ)元素);GPU用于完成圖形計(jì)算、渲染DisplayList(基礎(chǔ)元素)。

這里也找了一張各種場(chǎng)景下,硬件加速前后的流程與加速效果(Android6.0背景):

但是硬件加速也是有缺點(diǎn)的:

  • 啟用硬件加速需要更多資源,因此應(yīng)用會(huì)占用更多內(nèi)存。
  • 比較低的版本,由于有些Canvas API還沒(méi)有支持,所以使用硬件加速可能會(huì)有問(wèn)題。那么我們就可以手動(dòng)關(guān)閉某個(gè)view的硬件加速:
    myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)

Project Butter

黃油計(jì)劃,你有可能沒(méi)怎么聽(tīng)說(shuō),但是其實(shí)之前兩章內(nèi)容都提到過(guò),Android4.1之后,Google提出了黃油計(jì)劃,主要包括兩個(gè)內(nèi)容:

  • VSYNC
  • Triple Buffering(三重緩存)

這些都熟悉了吧,上兩節(jié)都說(shuō)過(guò)的,這里再簡(jiǎn)單提一下:

  • VSYNC

垂直同步信號(hào),每當(dāng)收到這個(gè)信號(hào)后,CPU就開(kāi)始準(zhǔn)備Buffer數(shù)據(jù),并在16ms之內(nèi)和GPU把屏幕需要的緩存數(shù)據(jù)準(zhǔn)備好。

  • Triple Buffering(三重緩存)

Android4.1之前,是雙緩存機(jī)制,大部分是沒(méi)問(wèn)題的。但是當(dāng)CPU/GPU繪制過(guò)程較長(zhǎng),超過(guò)一個(gè)vsync信號(hào)周期,一般是16ms,就會(huì)導(dǎo)致丟幀,CPU無(wú)法使用被GPU或者屏幕占用的緩存區(qū)。如果下一幀繪制如果又超時(shí),那么又會(huì)丟幀。

所以再加上一個(gè)緩存區(qū),這樣,CPU、GPU、Display三者都有各自的緩存區(qū),互不影響,就能保證時(shí)間的最大化利用,也就能減少上述的情況了。

RenderThread

RenderThread是在Android5.0提出的,從這個(gè)名字就能知道,它是一個(gè)線程,一個(gè)專(zhuān)門(mén)執(zhí)行GL命令的線程,也就是一部分的繪制工作。

有了它之后,當(dāng)CPU處理數(shù)據(jù)給GPU后,就不需要等GPU渲染完畢了,而是將一些繪制任務(wù)交給RenderThread,這樣就能減少主線程的工作,保證畫(huà)面的流暢。同時(shí)還提供了RenderNode,用來(lái)做view的屬性封裝,渲染幀的信息等等。

1.2 優(yōu)化方案

1.2.1 java代碼布局

我們一般都是用XML文件進(jìn)行布局,但是XML解析也是很耗時(shí)的,并在這個(gè)解析過(guò)程在主線程進(jìn)行。

所以我們有的時(shí)候也許可以通過(guò)Java代碼或者kotlin進(jìn)行View的創(chuàng)建?

理論中,這樣確實(shí)能減少布局加載的消耗時(shí)間,但是Java代碼創(chuàng)建View太麻煩了,而且無(wú)法可視化。

當(dāng)然,也有一些庫(kù)可以幫助我們將xml代碼轉(zhuǎn)換成java代碼,比如X2C(github.com/iReaderAndr… ),但是它并不支持所有的情況,比如merge標(biāo)簽,appCompat兼容控件等等。

所以我們需要在這之中找到平衡點(diǎn),有的時(shí)候,UI簡(jiǎn)單并且要求高性能的前提下,我們可以試試用這樣的方法,即用java代碼代替XmL代碼。

1.2.2 View重用

參照Recyclerview的做法,我們也可以將一些常用的view保存到緩存池中,這樣在不同的界面中就能復(fù)用緩存池里面的view。

1.2.3 異步創(chuàng)建view

這是Google提出的一個(gè)方案——AsyncLayoutInflater。它可以異步加載布局文件,并且回調(diào)給主線程,從而減少主線程耗時(shí)。簡(jiǎn)單貼下主要代碼:

new AsyncLayoutInflater(MainActivity.this).inflate(R.layout.activity_main, null, new AsyncLayoutInflater.OnInflateFinishedListener() {
        @Override
        public void onInflateFinished(@NonNull View view, int i, @Nullable ViewGroup viewGroup) {
        //回調(diào)給主線程
            setContentView(view);
    }
});

1.2.4 xml布局優(yōu)化

在寫(xiě)xml布局文件的時(shí)候,我們要做的也有很多,比如:

  • 減少布局嵌套。多使用ViewStub、Merge、ConstraintLayout來(lái)代替。
  • 優(yōu)化開(kāi)銷(xiāo)。RelativeLayout和 使用weight的LinearLayout 開(kāi)銷(xiāo)比較大,建議使用ConstraintLayout,LinearLayout代替。

1.2.5 異步布局框架Litho

Litho是Facebook開(kāi)源的一款在Android上高效建立UI的聲明式框架。

主要有以下特點(diǎn):

1)聲明式:它使用了聲明式的API來(lái)定義UI組件。

2)異步布局:它把 measurelayout 都放到了后臺(tái)線程,只留下了必須要在主線程完成的 draw,這大大降低了 UI 線程的負(fù)載

3)視圖扁平化:由于 Litho 使用了自有的布局引擎(Yoga),在布局階段就可以檢測(cè)不必要的層級(jí)、減少 ViewGroups,來(lái)實(shí)現(xiàn) UI 扁平化。

4)優(yōu)化 RecyclerView:Litho 還優(yōu)化了 RecyclerView 中 UI 組件的緩存和回收方法。

1.2.6 屏幕適配

關(guān)于屏幕適配問(wèn)題,也是老生常談了。主要有以下幾種方案:

  • dp適配方案。

這是系統(tǒng)自帶的適配單位,dp是基于屏幕物理分辨率一個(gè)抽象的單位,用于說(shuō)明與密度無(wú)關(guān)的尺寸和位置。所以它能在不同分辨率的手機(jī)上有相對(duì)大小的適配性。計(jì)算公式是:px=dp * (dpi/160)。但是dpi有可能會(huì)被人為調(diào)整(比如幾部相同分辨率不同尺寸的手機(jī)的ppi可能分別是是430,440,450,那么在Android系統(tǒng)中,可能dpi會(huì)全部指定為480),所以還是有可能在一些設(shè)備上出現(xiàn)適配問(wèn)題。

  • 寬高限定符適配方案。

簡(jiǎn)單地說(shuō),這個(gè)方案就是窮舉市面上所有的Android手機(jī)的寬高像素值。然后找到對(duì)應(yīng)的文件夾使用下面的資源文件所對(duì)應(yīng)的px值。

但是這方案有個(gè)缺陷,就是必須精確命中才行。比如1920x1080的手機(jī)就一定要找到1920x1080的限定符,否則就只能用統(tǒng)一的默認(rèn)的dimens文件了。

所以容錯(cuò)性太低,不推薦。

  • smallestWidth適配方案。

這個(gè)方案就是通過(guò)手機(jī)的寬度值來(lái)找到對(duì)應(yīng)限定符文件夾下的資源文件,可以看做寬高限定符屏幕適配方案的升級(jí)版。

假如我們的設(shè)計(jì)圖寬為360dp,那么就創(chuàng)建values-sw360dp文件夾,并添加資源文件:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <dimen name="dp_1">1dp</dimen>
    <dimen name="dp_2">2dp</dimen>
    <dimen name="dp_3">3dp</dimen>
    ...
    <dimen name="dp_359">359dp</dimen>
    <dimen name="dp_360">360dp</dimen>
</resources>

很簡(jiǎn)單,分為360份,然后我們實(shí)際寫(xiě)布局文件的時(shí)候,直接引用對(duì)應(yīng)的dimen值即可。

然后新建其他設(shè)備寬度的文件夾,并在每個(gè)文件夾里添加對(duì)應(yīng)的資源文件,這里以400dp為例:

├── src/main
│   ├── res
│   ├── ├──values
│   ├── ├──values-sw320dp
│   ├── ├──values-sw400dp
│   ├── ├──...
│   ├── ├──values-sw640dp
<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <dimen name="dp_1">1.1111dp</dimen>
    <dimen name="dp_2">2.2222dp</dimen>
    <dimen name="dp_3">3.3333dp</dimen>
    <dimen name="dp_4">4.4444dp</dimen>
    ...
    <dimen name="dp_359">398.8889dp</dimen>
    <dimen name="dp_360">400.0000dp</dimen>
</resources>

也就是說(shuō),所有的設(shè)備都分為360份了,這樣就能保證在不同寬度設(shè)備上都能有差不多的效果。

如果我們的設(shè)備寬度為400dp,那么就會(huì)調(diào)用values-sw400dp對(duì)應(yīng)的資源文件,如果找不到,就會(huì)向下查找。比如我們寬度是402dp,找不到對(duì)應(yīng)的,就會(huì)向上找到400dp對(duì)應(yīng)的資源文件,所以也有比較好的容錯(cuò)性。也是一個(gè)比較好的適配方案。

當(dāng)然這種重復(fù)性工作肯定不需要我們自己手動(dòng)去實(shí)現(xiàn),有專(zhuān)門(mén)的插件可以生成相應(yīng)的文件和文件夾,這里也推薦一個(gè):github.com/ladingwu/di…

  • 今日頭條適配方案。

這個(gè)大家應(yīng)該都很熟悉了,主要是通過(guò)動(dòng)態(tài)修改density值來(lái)保證所有設(shè)備的屏幕寬度都是固定的dp值。用到的公式就是px = density * dp。

比如設(shè)計(jì)圖寬為360dp,我們只要保證所有設(shè)備的寬度都是360dp就能適配了。而寬度的px值我們是已知的,所以就是要修改這個(gè) density 值來(lái)完成我們的適配目的。具體代碼我就不貼了,網(wǎng)上很多。

這種方案侵入性低,使用方便,是個(gè)不錯(cuò)的適配方案。

1.2.7 Flutter

Flutter是 Google 推出并開(kāi)源的移動(dòng)應(yīng)用開(kāi)發(fā)框架,開(kāi)發(fā)者可以通過(guò) Dart 語(yǔ)言開(kāi)發(fā) App,一套代碼同時(shí)運(yùn)行在 iOS 和 Android 平臺(tái)。

Flutter框架現(xiàn)在也是特別火,實(shí)際運(yùn)用到很多的大廠項(xiàng)目,比如閑魚(yú)今日頭條。它相對(duì)于Android其實(shí)是另外一套APP架構(gòu)了,它沒(méi)有基于系統(tǒng)本身的渲染引擎,而是app中自帶Skia引擎,虛擬機(jī)也是使用的Dart虛擬機(jī)。

主要有以下幾個(gè)特點(diǎn):

  • 跨平臺(tái):現(xiàn)在flutter至少可以跨5種平臺(tái),常見(jiàn)的平臺(tái):MacOS,Windows ,Linux ,Android ,iOS ,到目前為止,F(xiàn)lutter算是支持平臺(tái)最多的框架了。良好的跨平臺(tái)性,大大減少了開(kāi)發(fā)成本。
  • 絲滑般的體驗(yàn):使用Flutter內(nèi)置的Material Design(android風(fēng)格)和Cupertino(ios風(fēng)格)風(fēng)格組件,以及豐富的motion API,平滑而自然的滑動(dòng)效果和平臺(tái)感知,為用戶(hù)帶來(lái)全新的體驗(yàn)。
  • 響應(yīng)式框架:使用一系列基礎(chǔ)組件和響應(yīng)式框架,可以輕松構(gòu)建用戶(hù)界面。使用功能強(qiáng)大且靈活的API可以實(shí)現(xiàn)復(fù)雜的界面效果。
  • 支持插件:使用插件可以訪問(wèn)平臺(tái)本地API,如相機(jī),藍(lán)牙,WIFI等等。借助現(xiàn)有的Java,swift ,object c , c++代碼實(shí)現(xiàn)對(duì)原生系統(tǒng)的調(diào)用。
  • 60fps超高性能:Flutter編寫(xiě)的應(yīng)用可以達(dá)到60fps(每秒傳輸幀數(shù))。Flutter采用GPU渲染技術(shù),所以性能很好。完全可以勝任游戲開(kāi)發(fā)。

1.2.8 Jetpack Compose

Jetpack Compose 是用于構(gòu)建原生 Android 界面的新工具包

原來(lái)我們的布局文件都是寫(xiě)在xml文件中的,現(xiàn)在提供了一種新的view構(gòu)建方式,也就是Compose。

它是一種聲明式UI,不再使用xml,而是使用kotlin進(jìn)行UI布局。其實(shí)就跟我們之前提到的一點(diǎn),用java代碼去構(gòu)建view一樣的效果。這樣就減少了xml解析的時(shí)間,提高了效率。

聲明式UI。指的是只需要把界面聲明出來(lái),不需要手動(dòng)更新。比如我們這里的Compose只需要寫(xiě)一遍,后續(xù)的UI改變會(huì)隨著變量自動(dòng)更新。而傳統(tǒng)的xml布局方式就無(wú)法做到這一點(diǎn),屬于命令式UI,需要我們手動(dòng)命令紙牌屋UI的修改。

官方也是宣稱(chēng)有以下幾點(diǎn)優(yōu)勢(shì):

更少更直觀的代碼,更強(qiáng)大的功能,能提高開(kāi)發(fā)速度。

最后貼一段代碼,感受下Compose的寫(xiě)法:

class MainActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      Greeting("Android")
    }
  }
}
?
@Composable
fun Greeting(name: String) {
    Text (text = "Hello $name!")
}
  

復(fù)制

1.3 工具篇

1.3.1 Choreographer

Choreographer其實(shí)也是一個(gè)監(jiān)控應(yīng)用幀率的工具。它主要有以下特性:

  • 能獲取整體的幀率。
  • 能在線上使用。
  • 獲取的幀率幾乎是實(shí)時(shí)的。

主要原理就是利用postFrameCallback計(jì)算兩次繪制的間隔時(shí)間,簡(jiǎn)單貼下代碼:

private long mLastFrameTime;
Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
    @Override
    public void doFrame(long frameTimeNanos) {
        if (mLastFrameTime == 0) {
            mLastFrameTime = frameTimeNanos;
        }
        float diff = (frameTimeNanos - mLastFrameTime) / 1000000.0f;//得到毫秒,正常是 16.66 ms
        if (diff > 500) {
            double fps = (((double) (mFrameCount * 1000L)) / diff);
            mFrameCount = 0;
            mLastFrameTime = 0;
            Log.d("doFrame", "doFrame: " + fps);
        } else {
            ++mFrameCount;
        }
        Choreographer.getInstance().postFrameCallback(this);
    }
});

想細(xì)細(xì)研究的可以看看這個(gè)庫(kù)(github.com/friendlyrob…

1.3.2 LayoutInspector/Android Device Monitor

LayoutInspectorAndroidStudio種的一個(gè)布局檢查器,可以通過(guò)Tools > Layout Inspector找到,他可以檢查應(yīng)用中的某個(gè)界面的視圖結(jié)構(gòu),但是無(wú)法查看非調(diào)式狀態(tài)的應(yīng)用。

如果要看其他應(yīng)用的布局情況,可以使用Android Device Monitor,在Android Studio 3.1 以后,需要單獨(dú)從文件夾打開(kāi)了:

android-sdk/tools/monitor

1.3.3 Systrace

Systrace是分析Android性能問(wèn)題的神器,獲取Systrace文件的方式有兩種:

  • 一是AndroidSDK/tools目錄下,通過(guò)monitor.batAndroid Device Monitor可視化工具得到。
  • 二是通過(guò)python腳本獲取。

以上就是Android性能優(yōu)化系列篇UI優(yōu)化的詳細(xì)內(nèi)容,更多關(guān)于Android性能UI優(yōu)化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解Android Webview加載網(wǎng)頁(yè)時(shí)發(fā)送HTTP頭信息

    詳解Android Webview加載網(wǎng)頁(yè)時(shí)發(fā)送HTTP頭信息

    這篇文章主要介紹了詳解Android Webview加載網(wǎng)頁(yè)時(shí)發(fā)送HTTP頭信息的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Android滑動(dòng)事件沖突詳解(一)

    Android滑動(dòng)事件沖突詳解(一)

    這篇文章主要為大家詳細(xì)介紹了Android滑動(dòng)事件沖突,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-03-03
  • android仿微信好友列表功能

    android仿微信好友列表功能

    這篇文章主要介紹了android仿微信好友列表功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2018-04-04
  • Android RecyclerView基本使用詳解

    Android RecyclerView基本使用詳解

    這篇文章主要為大家詳細(xì)介紹了Android RecyclerView基本使用的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • Android設(shè)置theme中可能遇到的坑

    Android設(shè)置theme中可能遇到的坑

    Theme是一套UI控件和Activity的樣式,下面這篇文章主要給大家介紹了關(guān)于Android設(shè)置theme中可能遇到的坑的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-06-06
  • Android實(shí)現(xiàn)擴(kuò)大View點(diǎn)擊區(qū)域的三種方式

    Android實(shí)現(xiàn)擴(kuò)大View點(diǎn)擊區(qū)域的三種方式

    在 Android 應(yīng)用開(kāi)發(fā)中,有時(shí)候需要擴(kuò)大 View 的點(diǎn)擊區(qū)域以提高用戶(hù)交互的便利性,尤其是當(dāng)視圖元素較小或用戶(hù)界面密集時(shí),以下提供幾種擴(kuò)大點(diǎn)擊區(qū)域的思路,感興趣的小伙伴跟著小編一起來(lái)看看吧
    2024-08-08
  • Android中ImageView.src設(shè)置圖片拉伸、填滿(mǎn)控件的方法

    Android中ImageView.src設(shè)置圖片拉伸、填滿(mǎn)控件的方法

    最近公司有個(gè)需求,要展示客戶(hù)公司的企業(yè)形象,用一張圖片放在ImageView中實(shí)現(xiàn),但是發(fā)現(xiàn)圖片并沒(méi)有填滿(mǎn),而是在上下邊上留出了一點(diǎn)空白,下面這篇文章主要跟大家介紹了Android中ImageView.src設(shè)置圖片拉伸、填滿(mǎn)控件的方法,需要的朋友可以參考下。
    2017-06-06
  • Android仿微信朋友圈圖片查看器

    Android仿微信朋友圈圖片查看器

    這篇文章主要為大家詳細(xì)介紹了Android仿微信朋友圈圖片查看器的具體實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-05-05
  • Android ActionBar完全解析使用官方推薦的最佳導(dǎo)航欄(上)

    Android ActionBar完全解析使用官方推薦的最佳導(dǎo)航欄(上)

    Action Bar是一種新増的導(dǎo)航欄功能,在Android 3.0之后加入到系統(tǒng)的API當(dāng)中,它標(biāo)識(shí)了用戶(hù)當(dāng)前操作界面的位置,并提供了額外的用戶(hù)動(dòng)作、界面導(dǎo)航等功能
    2017-04-04
  • android AsyncTask詳細(xì)介紹

    android AsyncTask詳細(xì)介紹

    本篇文章主要主要介紹了AsyncTask介紹,AsyncTask,是android提供的輕量級(jí)的異步類(lèi),有興趣的同學(xué)可以了解一下。
    2016-11-11

最新評(píng)論