亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        安卓開發(fā)中的流暢性優(yōu)化方案研究

        2021-11-10 05:27:32張博涵
        電子設(shè)計(jì)工程 2021年21期
        關(guān)鍵詞:控件開發(fā)者代碼

        張博涵

        (武漢郵電科學(xué)研究院,湖北武漢430074)

        作為開發(fā)者,在日常開發(fā)工作中,性能優(yōu)化不是最難的問題,卻是最讓人頭疼的問題,因?yàn)閷?dǎo)致性能變差的原因很多,界面布局、功能邏輯、數(shù)據(jù)處理甚至是不同版本型號(hào)的安卓機(jī)都會(huì)導(dǎo)致不同的問題。性能優(yōu)化,是為了讓程序能夠運(yùn)行得更快、更省、更穩(wěn),先前的開發(fā)者們就性能問題雖提出了一些中肯的建議,但并不通用。文中將總結(jié)先前開發(fā)者們的經(jīng)驗(yàn),結(jié)合在日常開發(fā)中的應(yīng)用,從應(yīng)用啟動(dòng)速度、頁(yè)面加載速度以及操作響應(yīng)速度入手,提出能提升應(yīng)用程序流暢性的普適優(yōu)化建議和一些能使應(yīng)用程序跑得更快的通用方案。

        1 啟動(dòng)速度

        啟動(dòng)速度慢的原因,主要是源于在初次打開應(yīng)用時(shí),需要加載大量的功能邏輯和頁(yè)面顯示的資源。解決該問題可以采取以下幾點(diǎn)措施。

        1.1 減少onCreate()方法的啟動(dòng)時(shí)間

        一個(gè)Activity 的生命周期如圖1所示。由圖可知,onCreate()方法是打開一個(gè)Activity 時(shí)啟動(dòng)的第一個(gè)方法,其功能為完成啟動(dòng)一個(gè)Activity 的必要的初始化工作,如設(shè)置頁(yè)面的布局資源,初始化組件信息等。如果在onCreate()中的代碼過多,該環(huán)節(jié)耗時(shí)過長(zhǎng),則會(huì)導(dǎo)致啟動(dòng)速度變慢。

        圖1 Activity生命周期

        舉例說明,假如一個(gè)頁(yè)面有20 個(gè)控件,開發(fā)者將這些控件的所有屬性信息,全部放在MainActivity中的onCreate()方法內(nèi)去初始化。接下來(lái)進(jìn)入到命令提示符cmd 內(nèi),通過adb 指令的am start-W-n 包名/.LauncherActivity 指令來(lái)啟動(dòng)應(yīng)用程序,其中的TotalTime 即為該次啟動(dòng)App 所花的時(shí)間,大約為600 ms。

        接下來(lái)可以改變代碼,寫一個(gè)私有方法initView(),將初始化各個(gè)控件信息的語(yǔ)句全部放在這個(gè)方法里,而在onCreate()中只執(zhí)行initView()方法,解決了其中代碼太過冗雜的問題。重復(fù)上一段的指令,得到的應(yīng)用程序啟動(dòng)時(shí)間大約為550 ms。

        由以上對(duì)比可知,onCreate()內(nèi)代碼的數(shù)量直接決定應(yīng)用程序的啟動(dòng)時(shí)長(zhǎng),因?yàn)楸纠械膽?yīng)用程序非常簡(jiǎn)單,時(shí)長(zhǎng)差看起來(lái)并不大,但是在代碼量龐大的應(yīng)用程序中體現(xiàn)得尤其明顯,直接影響到用戶的使用體驗(yàn)。

        1.2 使用Adapter來(lái)提高效率

        Adapter 可以理解成是連接前端顯示和后端數(shù)據(jù)庫(kù)的適配器接口,是數(shù)據(jù)(Data)和UI(View)之間的重要橋梁,在經(jīng)常使用的ListView、GridView 等處都要用到創(chuàng)建對(duì)應(yīng)的Adapter 來(lái)配合使用[1-2]。Adapter、Data、View 三者的關(guān)系可以用圖2來(lái)表示。

        圖2 Adapter、View和Data之間的關(guān)系

        而Adapter 本身包含很多的接口,其具體的結(jié)構(gòu)如圖3所示。

        圖3 Adapter的結(jié)構(gòu)圖

        在日常開發(fā)中,開發(fā)者們常繪繼承BaseAdapter類,因?yàn)槠浒芏嘈枰獙?shí)現(xiàn)和重寫的方法,故具有較高的靈活性。其通常被用于ListView、GridView 等列表或表單型的布局當(dāng)中。通過重寫getView()方法來(lái)執(zhí)行和視圖相關(guān)的一些操作,每當(dāng)代碼運(yùn)行到這里的時(shí)候,都會(huì)調(diào)用getView()方法來(lái)重繪某個(gè)List,尋找該List 的item 布局文件,將其中的控件一個(gè)個(gè)再重新初始化,但很多情況下,使用者并不需要如此頻繁地重繪List,甚至在此次App 的使用中,該List只需要加載一次就夠了。在這種情況下,頻繁地重繪List 毫無(wú)疑問會(huì)影響頁(yè)面的啟動(dòng)速度,而且會(huì)造成大量的資源浪費(fèi),在布局復(fù)雜的時(shí)候會(huì)尤其明顯。為了解決該問題,開發(fā)者可以通過convertView+ViewHolder來(lái)進(jìn)行優(yōu)化。首先要寫出一個(gè)ViewHolder靜態(tài)類,接下來(lái)去判斷getView()方法內(nèi)的第二個(gè)參數(shù)convertView 是否為空,如果為空,則表示該List 還沒有被加載過,這樣便可以通過View.inflate()方法來(lái)尋找對(duì)應(yīng)控件的ID 并賦值給convertView,接下來(lái)獲取一個(gè)新的ViewHolder 對(duì)象,將convertView 中的各個(gè)控件綁定到Viewholder 上,再通過convertView 里的setTag()方法將ViewHolder 儲(chǔ)存。當(dāng)convertView判斷不為空的時(shí)候,便表示之前已經(jīng)加載過該List了,不用再重新繪制,此時(shí)便可以通過convertView 的getTag()方法直接調(diào)用儲(chǔ)存的ViewHolder,省掉了繪制的時(shí)間,大大縮短了頁(yè)面啟動(dòng)的速度[3-5]。

        1.3 減少主線程阻塞時(shí)間

        減少主線程阻塞的時(shí)間是為了防止ANR(Application Not Responding),當(dāng)用戶失去響應(yīng)超過5 s以上便會(huì)造成ANR。造成ANR 的原因有很多,但是總的來(lái)說,都是在主線程里進(jìn)行了太多耗時(shí)操作,比如加載圖片、申請(qǐng)網(wǎng)絡(luò)下載、操作數(shù)據(jù)庫(kù)等。從界面優(yōu)化的角度來(lái)說,一方面,開發(fā)者要保證進(jìn)行UI 操作的線程只處理一些跟UI 有關(guān)的操作,另一方面,如果實(shí)在無(wú)法避免一些耗時(shí)操作,則需要單獨(dú)開啟一個(gè)新線程來(lái)處理這些操作,并且通過Handler 來(lái)處理UI 線程和其他線程之間的交互。

        以上方法都是在代碼方面作出的改變,除了這些,開發(fā)者們也可以使用一些界面優(yōu)化的工具,比如Android SDK 提供的一個(gè)名叫Layoutopt 優(yōu)化工具,它可以告訴開發(fā)者哪些布局或者控件是多余的,可以刪除,也可以告訴開發(fā)者當(dāng)前界面布局太多或者嵌套太多,建議刪除或重新設(shè)計(jì)[7-9]。

        2 繪制速度

        渲染的意思是將各種布局控件繪制到屏幕上,渲染速度便代表了一個(gè)完整頁(yè)面呈現(xiàn)在用戶眼前的速度。如果想給用戶以流暢的使用體驗(yàn),便需要加快渲染速度。

        安卓的渲染機(jī)制如圖4所示,從Google 官方推出的性能優(yōu)化典范可以得知,60 fps 是當(dāng)前最佳的圖像顯示速度,所以目前安卓機(jī)的刷新頻率都被設(shè)置為60 fps,為了達(dá)到這個(gè)要求,開發(fā)者們需要在16 ms內(nèi)完成一次頁(yè)面刷新的操作。由圖4可知,系統(tǒng)每隔16 ms 便會(huì)發(fā)出一個(gè)垂直同步信號(hào)VSYNC 來(lái)觸發(fā)事件,并且在16 ms 之內(nèi)完成界面的更新與渲染。如此一來(lái)體現(xiàn)在用戶眼中的便是一次流的展示。

        圖4 流暢狀態(tài)下的安卓渲染機(jī)制

        不管因?yàn)槿魏卧驅(qū)е逻@一過程沒有在16 ms內(nèi)完成,便會(huì)出現(xiàn)掉幀現(xiàn)象,刷新的幀率也會(huì)下降。如此一來(lái)體現(xiàn)在用戶眼中的便是明顯的卡頓。掉幀狀態(tài)下的安卓渲染機(jī)制如圖5所示。

        圖5 掉幀狀態(tài)下的安卓渲染機(jī)制

        渲染的過程是由GPU 和CPU 協(xié)作完成,兩者有各自的分工、不同的潛在問題以及不同的解決方案,具體分工如圖6所示??偟膩?lái)說,便是通過HierarchyViewer 來(lái)檢測(cè)渲染的效率,進(jìn)而找出不必要的布局嵌套以及控件;通過智能手機(jī)上的Show GPU OverDraw 來(lái)檢測(cè)多余的背景[10]。

        圖6 渲染過程分工圖

        2.1 優(yōu)化布局避免過度繪制(OverDraw)

        過度繪制是屏幕上的某一個(gè)像素在同一幀時(shí)間里被繪制的次數(shù)過多,一般是布局套嵌過多或是背景顏色重疊導(dǎo)致的。開發(fā)者可以通過手機(jī)上的設(shè)置-開發(fā)者選項(xiàng)-調(diào)試GPU 過度繪制-顯示GPU 過度繪制來(lái)查看當(dāng)前頁(yè)面是否有過度繪制發(fā)生。屏幕上深紅色覆蓋區(qū)域表示過度繪制4 次;淺紅色覆蓋的區(qū)域表示被過度繪制了3 次;被藍(lán)色覆蓋區(qū)域表示被過度繪制了兩次;綠色覆蓋區(qū)域部分被過度繪制一次。如果一個(gè)界面被大量的深紅色和淺紅色覆蓋,則表示該頁(yè)面必須進(jìn)行優(yōu)化。

        布局優(yōu)化流程如下:先把容器之間的多層嵌套取消,改為單層結(jié)構(gòu)或兩層嵌套,如此一來(lái)雖然在表達(dá)能力上稍有欠缺,但在性能優(yōu)化上卻頗有成效。然后只給最外層容器設(shè)置白色背景,內(nèi)層容器和控件的背景設(shè)置全部取消,如此一來(lái)便可以避免多次繪制背景色。最后刪除一些沒有輸出內(nèi)容的控件,比如充當(dāng)分割區(qū)域的空文本框等,起到簡(jiǎn)化布局代碼的作用。優(yōu)化過的頁(yè)面應(yīng)當(dāng)是藍(lán)色區(qū)域占大多數(shù),紅色區(qū)域較少,這并不是完美的布局,但是在實(shí)際開發(fā)中是完全可以接受的。

        通過上述步驟可以發(fā)現(xiàn),在實(shí)際開發(fā)中,開發(fā)者首先要考慮布局容器的選擇和嵌套,安卓系統(tǒng)提供的Layout容器包括線性布局、相對(duì)布局、幀布局等,各有用處也各有優(yōu)劣。通常來(lái)說,描繪能力差的容器更加簡(jiǎn)潔,但或許需要多層嵌套。而描繪能力強(qiáng)的容器可以實(shí)現(xiàn)絕大多數(shù)頁(yè)面,或許也無(wú)需多層套嵌,但計(jì)算量也非常大。布局設(shè)置不一樣,即便功能一致,界面大體相同,但在細(xì)節(jié)上是有差異的。開發(fā)者需要判斷什么樣的差異可以忽略的,什么樣的差異不可接受。所以在實(shí)際開發(fā)中,要做到既能保證性能又能達(dá)到要求還能避免過度繪制是非常重要的。

        其次開發(fā)者可以考慮去掉多余的背景,主要有兩種情況:1)在使用某些安卓系統(tǒng)提供的主題時(shí)窗口會(huì)自帶背景,如果再在Layout 容器中設(shè)置背景便會(huì)造成重疊浪費(fèi),此時(shí)開發(fā)者可以選擇在Activity 的onCreat() 方法中,通過將語(yǔ)句 getWindow().setBackgroundDrawable()的賦值設(shè)為null 來(lái)取消背景。2)在設(shè)計(jì)布局界面時(shí),被覆蓋的部分的背景也要考慮去掉,這種情況非常多見,比如容器覆蓋容器,列表覆蓋容器,表格覆蓋容器等,被覆蓋的容器都應(yīng)設(shè)置背景為空。

        最后,開發(fā)者要著重注意App 的設(shè)計(jì)思路,要盡量避免過度設(shè)計(jì)。App 需要有個(gè)漂亮的外表,但是有些App 過于注重外表華麗,反而忽略了一個(gè)App簡(jiǎn)潔直觀實(shí)用才是最重要的,用戶并不會(huì)喜歡過于華麗復(fù)雜的東西,App 也會(huì)因此變得不流暢。

        除此之外,開發(fā)者們還可以通過ViewStub 來(lái)設(shè)置屬性并賦予指向的布局,只需要通過操作ViewStub來(lái)決定是否顯示指定的布局;也可以使用draw9patch制作圖片,給ImageView 制作背景來(lái)充當(dāng)邊框,將重疊部分設(shè)置為透明,來(lái)滿足減少過度繪制的要求等??傊幚聿煌那闆r,需要不同的思路,使用不同的工具,才能保持性能和流暢度之間的平衡。針對(duì)過度繪制的優(yōu)化方案沒有誰(shuí)對(duì)誰(shuí)錯(cuò),只有合適與否。

        2.2 降低onDraw()方法的復(fù)雜度

        在實(shí)際開發(fā)中,安卓系統(tǒng)提供的View 通常是無(wú)法滿足要求的,此時(shí)便需要自定義View。自定義View 的繪制大致分以下步驟:onMeasure()方法用于測(cè)量布局寬高尺寸以及位置;onLayout()方法用于排列控件;onDraw()方法用于繪制。自定義View 繪制流程如圖7所示。

        圖7 自定義View繪制流程圖

        由于onDraw()方法的作用是將已經(jīng)測(cè)好寬高尺寸的View 畫出來(lái),所以經(jīng)常面臨重復(fù)多次調(diào)用的情況。開發(fā)者很難去限制其調(diào)用次數(shù),所以更多時(shí)候會(huì)選擇盡可能地簡(jiǎn)化onDraw()方法,正如前文中簡(jiǎn)化onCreate()方法一樣。一方面,開發(fā)者要避免在onDraw()方法里創(chuàng)造過多的局部變量,這些局部變量會(huì)伴隨方法的調(diào)用而被創(chuàng)建,在一瞬間會(huì)占用較多的資源,而如此反復(fù)下來(lái)必然會(huì)降低效率。另一方面,開發(fā)者要把耗時(shí)的操作移出onDraw(),比如在繪制界面時(shí)需要從網(wǎng)絡(luò)上請(qǐng)求一張圖片顯示出來(lái),這種情況下需要另開新線程來(lái)作處理,然后通過Handler通知onDraw(),圖片請(qǐng)求好了,可以加載即可。

        3 響應(yīng)速度

        響應(yīng)速度變慢,出現(xiàn)的最常見的情況就是ANR。當(dāng)出現(xiàn)ANR 時(shí),程序會(huì)失去響應(yīng),屏幕會(huì)直接在某個(gè)界面卡死。如前文提到的一樣,造成ANR的原因還是由于把一些耗時(shí)的操作放在了主線程內(nèi)進(jìn)行,如果廣播或者服務(wù)在一段時(shí)間內(nèi)沒有響應(yīng)就必會(huì)觸發(fā)ANR。解決方法無(wú)外乎以下幾種,異步實(shí)現(xiàn)、新開線程、消息機(jī)制等[11-12]。

        除了上述內(nèi)容,在實(shí)際開發(fā)中遇到的問題數(shù)不勝數(shù),只能結(jié)合實(shí)際情況去考慮。比如在處理即時(shí)更新的界面時(shí),如何既能保證刷新頻率,又能限制資源消耗?使用動(dòng)畫時(shí)如何合理選擇框架,是否需要使用硬件加速?某些使用不頻繁的界面是退出再加載,還是隱藏再顯示?諸如此類的問題都將是開發(fā)過程中的難題[13-14]。

        4 結(jié) 論

        隨著技術(shù)的發(fā)展和手機(jī)的普及,應(yīng)用程序的使用必然越來(lái)越廣泛,開發(fā)者們也需要去滿足用戶更多的要求。文中提供的思路都是在代碼端就可以實(shí)現(xiàn)的,不用考慮手機(jī)型號(hào)和安卓版本,也具有較為廣泛的適用性。而測(cè)試結(jié)果表明,合理的代碼設(shè)計(jì)不僅能夠縮短各種操作耗費(fèi)的時(shí)間,也節(jié)省了系統(tǒng)資源,使用戶的體驗(yàn)更出色,在代碼量大的程序上顯現(xiàn)更加明顯,而且通過精簡(jiǎn)、合理規(guī)劃代碼,降低代碼的耦合度,也會(huì)增加代碼的可讀性,可以使開發(fā)者們更輕松地維護(hù)和更新代碼。而除了流暢性,還有穩(wěn)定性、節(jié)省性等諸多評(píng)價(jià)一個(gè)程序好壞的指標(biāo),文中并未討論。在實(shí)際開發(fā)中,如何在兼顧這些指標(biāo)的同時(shí),做到功能不打折扣,外觀盡量美觀,操作簡(jiǎn)單清晰是開發(fā)者們無(wú)法回避的難題。只有不斷鉆研,廣納建議,收集用戶反饋,才能做出跟得上技術(shù)進(jìn)步和審美發(fā)展的出色的應(yīng)用程序[15-16]。

        猜你喜歡
        控件開發(fā)者代碼
        創(chuàng)世代碼
        創(chuàng)世代碼
        創(chuàng)世代碼
        創(chuàng)世代碼
        關(guān)于.net控件數(shù)組的探討
        軟件(2018年7期)2018-08-13 09:44:42
        16%游戲開發(fā)者看好VR
        CHIP新電腦(2016年3期)2016-03-10 13:06:42
        iOS開發(fā)者調(diào)查
        電腦迷(2015年8期)2015-05-30 12:27:10
        iOS開發(fā)者調(diào)查
        電腦迷(2015年4期)2015-05-30 05:24:09
        就這樣玩會(huì)VBA中常見的自定義控件
        電腦迷(2012年24期)2012-04-29 00:44:03
        安卓開發(fā)者之煩惱
        99久久99久久精品国产片果冻| 亚洲成人av在线蜜桃| 日本伊人精品一区二区三区| 欧美人和黑人牲交网站上线| 日韩中文网| 男男互吃大丁视频网站| 久久99热只有频精品8国语| 亚洲国产精品无码久久98| 亚洲av理论在线电影网| 麻豆国产VA免费精品高清在线| 成人国产一区二区三区av| 国产综合色在线视频区| 国产剧情av麻豆香蕉精品| 在线偷窥制服另类| 麻豆成人久久精品一区| 天天做天天添av国产亚洲| 国产自国产在线观看免费观看| 乱色视频中文字幕在线看| 无色码中文字幕一本久道久| 中文字幕一精品亚洲无线一区| 18禁美女裸体网站无遮挡| 青青青草国产熟女大香蕉| 久久精品不卡一区二区三区| 一区二区三区乱码在线 | 欧洲| 亚洲欧美日韩激情在线观看| 日本免费一区精品推荐| 美腿丝袜诱惑一区二区| 日韩免费无码一区二区三区| 精品人妻丰满久久久a| 国产成人综合久久大片| 久久久中文久久久无码| 久久精品岛国av一区二区无码| 久久伊人网久久伊人网| 亚洲中文字幕舔尻av网站| 亚洲伊人成综合网| 中文字幕国产精品中文字幕| 日韩精品中文字幕第二页| 国产精品泄火熟女| 伊人网综合| 最新日本久久中文字幕 | 少妇精品无码一区二区三区|