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

Android Fresco圖片加載優(yōu)化的方案

 更新時(shí)間:2021年03月17日 10:52:30   作者:彭也  
這篇文章主要介紹了Android Fresco圖片加載優(yōu)化的方案,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下

優(yōu)化背景

一般情況下,F(xiàn)resco圖片加載需使用SimpleDraweeView,這個(gè)控件并不能自動(dòng)根據(jù)自身的尺寸按需加載圖片,即一個(gè) N×N 的UI控件,背后加載的實(shí)際圖片可能是 2N×2N。這就導(dǎo)致了實(shí)際應(yīng)用運(yùn)行過(guò)程中的內(nèi)存使用效率不高,需要針對(duì)其進(jìn)行內(nèi)存優(yōu)化。

在一些入門(mén)級(jí)硬件設(shè)備上,表現(xiàn)得尤為明顯,隨著程序的運(yùn)行時(shí)間的增長(zhǎng),OOM的風(fēng)險(xiǎn)也不斷加大。

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,即此時(shí)SimpleDraweeView會(huì)按照網(wǎng)絡(luò)上的原圖尺寸進(jìn)行加載,內(nèi)存占用大小為 8294475Bytes = 7.91Mb。一張圖片占用近8Mb,在圖片顯示十分豐富的頁(yè)面場(chǎng)景中,圖片總內(nèi)存占用大小將特別美麗,萬(wàn)一這個(gè)頁(yè)面又內(nèi)存泄漏了,那就更美麗了。

如果只加載 480×270 大小的圖片,內(nèi)存占用為 518475Bytes = 0.49Mb。相較于原來(lái) 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);

注意這個(gè)方案在低版本中默認(rèn)只支持jpg圖片,如需支持其它圖片格式,需在設(shè)置image pipeline時(shí)添加isDownSample配置。同時(shí)對(duì)于產(chǎn)生的圖片的尺寸,只能粗略地控制,圖片不能修改為確定的尺寸。

.setDownsampleEnabled(true)

這個(gè)方案有個(gè)顯著的缺點(diǎn),那就是頁(yè)面適配性極差,需要配合View層的生命周期在確保能夠動(dòng)態(tài)獲取到控件寬高的時(shí)機(jī)進(jìn)行調(diào)用,對(duì)于一個(gè)成熟的項(xiàng)目工程,代碼改動(dòng)量過(guò)大,優(yōu)化成本過(guò)高。 這里采用編寫(xiě)SimpleDraweeView的子類(lèi)進(jìn)行優(yōu)化,利用向上轉(zhuǎn)型,盡可能的減小View層代碼的改動(dòng),只需要修改xml布局文件中的控件聲明即可。 方案架構(gòu)圖如下:

其中DesiredSimpleDraweeView為SimpleDraweeView的子類(lèi),在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ù)寫(xiě)setImageURI(Uri,Object)方法,暫存uri和callerContext,在onWindowFoucusChanged回調(diào)之后再根據(jù)控件寬高進(jìn)行圖片的加載。 這樣,利用向上轉(zhuǎn)型,View層的代碼無(wú)需改動(dòng),xml文件中替換控件聲明后即可顯著提高內(nèi)存利用率。

注意事項(xiàng)

性能優(yōu)化是條永無(wú)止境的道路,沒(méi)有最牛的方案,只有最合適的方案。如果對(duì)于圖片加載尺寸想要精確控制,按需加載,Glide或許是更好的選擇。

以上就是Android Fresco圖片加載優(yōu)化的方案的詳細(xì)內(nèi)容,更多關(guān)于Android Fresco圖片加載優(yōu)化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論