Android Fresco圖片加載優(yōu)化的方案
優(yōu)化背景
一般情況下,F(xiàn)resco圖片加載需使用SimpleDraweeView,這個控件并不能自動根據(jù)自身的尺寸按需加載圖片,即一個 N×N 的UI控件,背后加載的實(shí)際圖片可能是 2N×2N。這就導(dǎo)致了實(shí)際應(yīng)用運(yùn)行過程中的內(nèi)存使用效率不高,需要針對其進(jìn)行內(nèi)存優(yōu)化。
在一些入門級硬件設(shè)備上,表現(xiàn)得尤為明顯,隨著程序的運(yùn)行時間的增長,OOM的風(fēng)險也不斷加大。
Fresco版本:1.13.0
數(shù)據(jù)記錄
聲明控件大小為 480×270
<com.facebook.drawee.view.SimpleDraweeView android:id="@+id/simple_drawee_view" android:layout_width="480dp" android:layout_height="270dp" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />
加載圖片代碼,調(diào)用Fresco的setImageURI
val mImageUrl = "https://static.runoob.com/images/demo/demo4.jpg" val simple_drawee_view = findViewById<SimpleDraweeView>(R.id.simple_drawee_view) simple_drawee_view.setImageURI(mImageUrl)
運(yùn)行后dump內(nèi)存如下,可以發(fā)現(xiàn)內(nèi)存中的圖片尺寸為1920×1080,即此時SimpleDraweeView會按照網(wǎng)絡(luò)上的原圖尺寸進(jìn)行加載,內(nèi)存占用大小為 8294475Bytes = 7.91Mb。一張圖片占用近8Mb,在圖片顯示十分豐富的頁面場景中,圖片總內(nèi)存占用大小將特別美麗,萬一這個頁面又內(nèi)存泄漏了,那就更美麗了。
如果只加載 480×270 大小的圖片,內(nèi)存占用為 518475Bytes = 0.49Mb。相較于原來 1920×1080 尺寸,內(nèi)存減小了 94%!
優(yōu)化方案
Fresco提供了resize api,使得調(diào)用者在圖片解碼前可以修改內(nèi)存中圖片的大小,api大致如下
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri) .setResizeOptions(new ResizeOptions(width, height)) .build(); PipelineDraweeController controller = Fresco.newDraweeControllerBuilder() .setOldController(mDraweeView.getController()) .setImageRequest(request) .build(); mSimpleDraweeView.setController(controller);
注意這個方案在低版本中默認(rèn)只支持jpg圖片,如需支持其它圖片格式,需在設(shè)置image pipeline時添加isDownSample配置。同時對于產(chǎn)生的圖片的尺寸,只能粗略地控制,圖片不能修改為確定的尺寸。
.setDownsampleEnabled(true)
這個方案有個顯著的缺點(diǎn),那就是頁面適配性極差,需要配合View層的生命周期在確保能夠動態(tài)獲取到控件寬高的時機(jī)進(jìn)行調(diào)用,對于一個成熟的項(xiàng)目工程,代碼改動量過大,優(yōu)化成本過高。 這里采用編寫SimpleDraweeView的子類進(jìn)行優(yōu)化,利用向上轉(zhuǎn)型,盡可能的減小View層代碼的改動,只需要修改xml布局文件中的控件聲明即可。 方案架構(gòu)圖如下:
其中DesiredSimpleDraweeView為SimpleDraweeView的子類,在onWindowFocusChanged方法回調(diào)中可以明確獲知控件的具體寬高,之后再進(jìn)行圖片加載操作。
public class DesiredSimpleDraweeView extends SimpleDraweeView { Uri mUri; Object mCallerContext; public DesiredSimpleDraweeView(Context context) { super(context); } @Override public void setImageURI(Uri uri, Object callerContext) { mUri = uri; mCallerContext = callerContext; } private void setImageURI(int width, int height) { try { ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(mUri) .setResizeOptions(new ResizeOptions(width, height)) .build(); DraweeController controller = getControllerBuilder() .setOldController(getController()) .setImageRequest(imageRequest) .build(); setController(controller); } catch (Exception ex) { ex.printStackTrace(); } } @Override public void onWindowFocusChanged(boolean hasWindowFocus) { super.onWindowFocusChanged(hasWindowFocus); if (hasWindowFocus) { setImageURI(getWidth(), getHeight()); } } }
復(fù)寫setImageURI(Uri,Object)方法,暫存uri和callerContext,在onWindowFoucusChanged回調(diào)之后再根據(jù)控件寬高進(jìn)行圖片的加載。 這樣,利用向上轉(zhuǎn)型,View層的代碼無需改動,xml文件中替換控件聲明后即可顯著提高內(nèi)存利用率。
注意事項(xiàng)
性能優(yōu)化是條永無止境的道路,沒有最牛的方案,只有最合適的方案。如果對于圖片加載尺寸想要精確控制,按需加載,Glide或許是更好的選擇。
以上就是Android Fresco圖片加載優(yōu)化的方案的詳細(xì)內(nèi)容,更多關(guān)于Android Fresco圖片加載優(yōu)化的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
android開發(fā)教程之獲取power_profile.xml文件的方法(android運(yùn)行時能耗值)
在Android手機(jī)中,對于手機(jī)中的每個部件(cpu、led、gps、3g等等)運(yùn)行時對應(yīng)的能耗值都放在power_profile.xml文件中2014-02-02Android?Flutter實(shí)現(xiàn)"斑馬紋"背景的示例代碼
本文將通過實(shí)現(xiàn)一個canvas繪制斑馬紋類。使用Stack布局,將斑馬紋放在下方作為背景板,需要展示的內(nèi)容在上方。從而實(shí)現(xiàn)?“斑馬紋”背景,感興趣的可以了解一下2022-06-06Android onbackpressed實(shí)現(xiàn)返回鍵的攔截和彈窗流程分析
很多網(wǎng)友不明白如何在Android平臺上捕獲Back鍵的事件,Back鍵是手機(jī)上的后退鍵,一般的軟件不捕獲相關(guān)信息可能導(dǎo)致你的程序被切換到后臺,而回到桌面的尷尬情況,在Android上有兩種方法來獲取該按鈕的事件2023-01-01Flutter框架解決盒約束widget和assets里加載資產(chǎn)技術(shù)
這篇文章主要為大家介紹了Flutter框架解決盒約束widget和assets里加載資產(chǎn)技術(shù)運(yùn)用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12Android自定義密碼輸入框的簡單實(shí)現(xiàn)過程
在最近的項(xiàng)目中,用戶需要輸入密碼,不想用系統(tǒng)鍵盤,就寫了一個自定義鍵盤,下面這篇文章主要給大家介紹了關(guān)于Android自定義密碼輸入框的簡單實(shí)現(xiàn)過程,需要的朋友可以參考下2021-11-11