詳談高大上的圖片加載框架Glide -應用篇

在Android設備上,加載網絡圖片一直是一個頭疼的問題,因為Android設備種類繁多(當然最主要的是配置),處理的稍不周到輕則應用卡頓,嚴重者就會出現OOM的,導致程序掛掉。現如今網絡上有很多圖片庫,如 Universal-Image-Loader,Picasso,FrescoGlide等等。相信列舉出的這幾個庫大家都不陌生,這也是目前最火的圖片庫了。由于個人的喜好原因(主要是別人介紹說Glide庫比較NB),所以就開始研究學習Glide。

Glide庫和Picasso庫有極大的相似性,編碼風格也幾近相同,不過Glide缺有著更為強大的功能。它在緩存處理方面有著很大的優勢并且支持加載Gif動畫以及本地Video。這個庫在谷歌開源庫中也有應用。如此好東西,心動不如行動,現在開始我們的學習之旅吧。


源碼【傳送門】


配置

使用Glide的第一步是現在我們的builde.gradle

dependencies {
  compile 'com.github.bumptech.glide:glide:3.7.0'
  compile 'com.android.support:support-v4:19.1.0'
}

配置gradle文件后,我們就可以使用Glide了。上代碼

Glide.with(context).load("http://img2.3lian.com/2014/f6/173/d/51.jpg").into(imageView);

看著很簡單吧,一句話就可以實現圖片下載和展示。我們看到Glide使用建造者模式加載圖片。

RequestManager with(Context context)
RequestManager with(Activity activity)
RequestManager with(FragmentActivity activity)

我們看到with()可接受三種參數,這也是Glide的亮點,它能根據傳入參數Activity/Fragment的生命周期保持一致,去暫停和執行圖片加載,這也節省了不必要的流量浪費。

加載圖片方式

DrawableTypeRequest<String> load(String string)
DrawableTypeRequest<Uri> load(Uri uri)
DrawableTypeRequest<File> load(File file)
DrawableTypeRequest<Integer> load(Integer resourceId)
DrawableTypeRequest<URL> load(URL url)

String參數加載

Glide.with(this).load("http://img2.3lian.com/2014/f6/173/d/51.jpg").into(imageView);

資源文件加載

 int  resourceId=R.mipmap.image;
 Glide.with(context).load(resourceId).into(imageView);

本地文件加載

File file = new File(Environment.getExternalStorageDirectory() + File.separator +  "image", "image.jpg");
Glide.with(this).load(file).into(imageView);

Uri加載

File file = new File(Environment.getExternalStorageDirectory() + File.separator +  "image", "image.jpg");
Uri uri = Uri.fromFile(file);
Glide.with(this).load(uri).into(imageView);//uri加載方式

URL方式

該方式在源碼中已經標記@Deprecated

        try {
           url=new URL("http://img2.3lian.com/2014/f6/173/d/51.jpg");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    Glide.with(this).load(url).into(imageView);//URL加載方式    

設置占位圖片##

在上面的處理中,我們之間將加載成功的圖片展示到ImageView,這樣會不會看起來很突兀?是的,Glide為我們提供了設置占位符,他可以讓我們知道圖片是否加載成功,等

placeholder###

我們都知道,圖片加載是不確定的,加載成功需要的時間也是不確定的,而在加載這段時間,我們可以通過placeholder設置給ImageView一個占位符,圖片上可以提示正在加載中之類的,當然可以任何你要的效果,

Glide.with(context).load("http://img2.3lian.com/2014/f6/173/d/55.jpg").placeholder(R.mipmap.place).into(imageView);

error###

當然除了加載成功前我們設置了占位符,那么如果加載錯誤(網絡原因及url非法原因等導致圖片沒有加載成功),我們填充一個圖片到ImageView提示用戶當前圖片加載失敗。

Glide.with(context).load("http://img2.3lian.com/2014/f6/173/d/55.jpg").error(R.mipmap.error).into(imageView);

此時你可能想如何知道圖片加載失敗的具體原因呢?Glide為我們提供了listener()方法,接收RequestListener對象

        //設置錯誤監聽
         RequestListener<String,GlideDrawable> errorListener=new RequestListener<String, GlideDrawable>() {
            @Override
            public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {

                Log.e("onException",e.toString()+"  model:"+model+" isFirstResource: "+isFirstResource);
                imageView.setImageResource(R.mipmap.ic_launcher);
                return false;
            }

            @Override
            public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                Log.e("onResourceReady","isFromMemoryCache:"+isFromMemoryCache+"  model:"+model+" isFirstResource: "+isFirstResource);
                return false;
            }
        } ;

我們看到有兩個回調方法,通過onException是圖片加載異常回調,onResourceReady是加載成功的回調。我們可以測試不同情況打印的日志

  • 正確的url首次加載
onResourceReady: isFromMemoryCache:false  model:http://img2.3lian.com/2014/f6/173/d/51.jpg isFirstResource: true
  • 正確的url第二次加載
onResourceReady: isFromMemoryCache:true  model:http://img2.3lian.com/2014/f6/173/d/51.jpg isFirstResource: true
  • 錯誤的url
onException: java.io.IOException: Request failed 404: Not Found  model:http://img2.3lian.com/2014/f6/173/d/511.jpg isFirstResource: true
  • 錯誤的url(非圖片類型url)
onException: java.io.FileNotFoundException: No such file or directory  model:www.baidu.com isFirstResource: true
  • 無網絡
onException: java.net.UnknownHostException: Unable to resolve host "img2.3lian.com": No address associated with hostname  model:http://img2.3lian.com/2014/f6/173/d/51.jpg isFirstResource: true

通過日志我們很容易看出異常的原因,因此,我們可以針對不同的操作情形,書寫自己的處理給用戶反饋。

crossFade###

通過上面的分析,我們實現了占位圖填充ImageView,但是我們依然發現其中有些不足,因為圖片的轉換并沒有實現平滑過渡效果,實際新api已經默認實現一個漸入漸出的動畫效果,默認是300ms.

Glide.with(context).load("http://img2.3lian.com/2014/f6/173/d/51.jpg").error(R.mipmap.error).placeholder(R.mipmap.place).crossFade().into(imageView);

crossFade()還可以接收一個int型的參數,用它來指定動畫執行的時間,例如我們設置動畫執行的時間是2s

Glide.with(context).load("http://img2.3lian.com/2014/f6/173/d/51.jpg").error(R.mipmap.error).placeholder(R.mipmap.place).crossFade(2000).into(imageView);

既然我們能添加一個漸入漸出的動畫效果,那么如果想直接顯示圖片而沒有任何淡入淡出效果,該作何處理,我們可以使用dontAnimate()方法,這是直接顯示你的圖片,而不是淡入顯示到 ImageView。

圖片調整##

Glide加載圖片大小是自動調整的,他根據ImageView的尺寸自動調整加載的圖片大小,并且緩存的時候也是按圖片大小緩存,每種尺寸都會保留一份緩存,如果圖片不會自動適配到 ImageView,調用 override(horizontalSize, verticalSize) 。這將在圖片顯示到 ImageView之前重新改變圖片大小

        //Glide.with(context).load("http://img2.3lian.com/2014/f6/173/d/51.jpg").dontAnimate().override(400,600).fitCenter().into(imageView);

注意override接收的參數是像素(px)

縮放###

對于任何圖像操作,調整大小可能讓圖片失真。但是我們要盡可能的避免發生這種情況發生。Glide 提供了兩個圖形裝換的操作提供了兩個標準選項:centerCrop 和 fitCenter

  • centerCrop
    這個方法是裁剪圖片,當圖片比ImageView大的時候,他把把超過ImageView的部分裁剪掉,盡可能的讓ImageView 完全填充,但圖像可能不會全部顯示
        Glide.with(context).load("http://img2.3lian.com/2014/f6/173/d/51.jpg").centerCrop().into(imageView);

  • fitCenter
    它會自適應ImageView的大小,并且會完整的顯示圖片在ImageView中,但是ImageView可能不會完全填充

加載Gif

加載Gif動畫也是Glide的一大優勢,它很簡單的就能實現Gif的加載與顯示

加載Gif文件
Glide.with(context).load("http://img1.3lian.com/2015/w4/17/d/64.gif").into(imageView);

是不是很簡單,依然是一句話就實現顯示網絡上Gif功能。Glide還提供了Gif相關操作的兩個方法。如果我們想將Gif顯示成圖片的第一幀只需要使用asBitmap()方法即可。如果我們有這個需求,就是嚴格顯示成Gif,那么當傳入了一個非Gif 的url時,我們當做錯誤處理。此時我們可以使用asGif()方法

        Glide.with(context).load("http://img2.3lian.com/2014/f6/173/d/51.jpg").asGif().error(R.mipmap.error).placeholder(R.mipmap.place).into(imageView);

Glide 將會把這個 load 當成失敗處理。這樣做的的好處是,.error() 回調被調用并且錯誤占位符被顯示,如果url是Gif,那么會沒什么變化,這樣就檢查了load參數是否為Gif.

Glide網絡加載方式##

Glide內部默認是通過HttpURLConnection網絡方式加載圖片的,并且支持OkHttp,Volley

集成OkHttp###

在gradle文件加入下面代碼

    //自動集成okhttp
    compile 'com.github.bumptech.glide:okhttp-integration:1.4.0@aar'
    compile 'com.squareup.okhttp:okhttp:2.2.0'

集成Volley###

    //自動集成volley
    compile 'com.github.bumptech.glide:volley-integration:1.4.0@aar'
    compile 'com.mcxiaoke.volley:library:1.0.19'

Gradle 會自動合并必要的 GlideModule 到Android.Manifest。Glide 會認可在 manifest 中的存在,然后使用 所集成的網絡連接。

自定義動畫##

在前面我們已經提到過Glide提供了一個漸入漸出的動畫效果,當然該動畫不是那么酷炫,而且有時并不能達到我們想要的效果,不過Glide給我們提供了animate()方法,我們可以通過此方法實現我們自定義的動畫效果。

animate(int animationId)

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillAfter="false"
    android:duration="3000">

    <scale
        android:duration="@android:integer/config_longAnimTime"
        android:fromXScale="0.1"
        android:fromYScale="0.1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1"
        android:toYScale="1"/>
    <rotate
        android:fromDegrees="0"
        android:toDegrees="90"
        android:pivotX="50%"
        android:pivotY="50%"
        />
</set>

上面我們實現了一個圖片從小變大并且有一個旋轉效果的動畫,當然你可以在此文件書寫任何你想要實現的動畫。

        Glide.with(context).load("http://img2.3lian.com/2014/f6/173/d/51.jpg").animate(R.anim.anim).into(imageView);

java文件設置動畫

我們也可以通過Animator實現動畫,如下

        //java文件設置動畫
        ViewPropertyAnimation.Animator animator=new ViewPropertyAnimation.Animator() {
            @Override
            public void animate(View view) {
              view.setAlpha(0f);
                ObjectAnimator fadeAnim = ObjectAnimator.ofFloat( view, "alpha", 0f, 1f );
                fadeAnim.setDuration( 2500 );
                fadeAnim.start();
            }
        };
        Glide.with(context).load("http://img2.3lian.com/2014/f6/173/d/51.jpg").animate(animator).into(imageView);

Target##

Glide不但可以把圖片、視頻劇照、GIF動畫加載到View,還可以加載到自定義的Target實現中。Target就是使用Glide獲取到資源之后資源作用的目標,我們通常是用Glide加載完資源后顯示到ImageView中,這個ImageView就是目標.

SimpleTarget###

        //SimpleTarget
        SimpleTarget target = new SimpleTarget<Drawable>(){
            @Override
            public void onResourceReady(Drawable resource, GlideAnimation<? super Drawable> glideAnimation) {
                textView.setBackground(resource);
            }
        };
       Glide.with(context)
                .load("http://img2.3lian.com/2014/f6/173/d/51.jpg")
                .animate(animator)
                .into(target);

上面的代碼我們將TextView作為Target,將加載的圖片設為背景,對于SimpleTarget是接收的泛型數據,如果我們需要Bitmap對象,我們將泛型為Bitmap.以及其它我們想要的類型。
我們還可以指定加載的寬和高,如下,設置寬和高都是100,單位是px

        SimpleTarget target = new SimpleTarget<Drawable>(100,100){
            @Override
            public void onResourceReady(Drawable resource, GlideAnimation<? super Drawable> glideAnimation) {
                textView.setBackground(resource);
            }
        };

ViewTarget###

如果你想加載一個圖片到View中,但是你想觀察或者覆蓋Glide的默認行為。你可以覆蓋ViewTarget或者它的子類。
當你想讓Glide來獲取view的的大小,但是由自己來啟動動畫和設置資源到view中,ViewTarget是個不錯的選擇。如果你要加載一個圖片到ImageView之外的自定義view中,那么ImageViewTarget或者它的子類就不能滿足你的要求,此時繼承ViewTarget就特別合適。
你可以靜態的定義一個ViewTarget的子類,或者傳遞一個匿名內部類到你的加載調用里:

Glide.with(yourFragment)
    .load(yourUrl)
    .into(new ViewTarget<YourViewClass, GlideDrawable>(yourViewObject) {
        @Override
        public void onResourceReady(GlideDrawable resource, GlideAnimation anim) {
            YourViewClass myView = this.view;
            // Set your resource on myView and/or start your animation here.
        }
    });

說明:
加載一張靜態的圖片或者一張GIF動態圖,可以在load后面加上asBitmap()/asGif()
.Load(url)會通過asXXX()替換ViewTarget當中的GlideDrawable參數,也可以通過實現LifecycleLisener,給target設置一個回調

轉換 transform##

在圖片顯示之前,我們可以通過transform對圖像做一些處理,達到我們想要的圖片效果,例如我們改變圖片的大小,范圍,顏色等。Glide提供了兩種基本的圖片轉換即:fitCenter 和 centerCrop,前面已介紹過。這次我們來了解如何自定義轉換效果,例如如果我們想展示一個圓形圖片或者一個具有圓角的圖片該如何處理?(圓形頭像)
為了自定義轉換,我們需要創建一個新的類實現了 Transformation 接口。不過如果我們只是做圖片的轉換可以直接用Glide封裝好的BitmapTransformation抽象類。圖像轉換操作只需要在transform里實現。getId() 方法描述了這個轉換的唯一標識符。Glide 使用該鍵作為緩存系統的一部分,為了避免意外的問題,你要確保它是唯一的
接下來先實現一個圓角的圖片

推薦一個開源的轉換庫glide-transformations,它實現了很多轉換,我們只要集成直接使用 glide-transformationsGithub地址

這里寫圖片描述

 /**
     * 將圖像轉換為四個角有弧度的圖像
     */
    public class GlideRoundTransform extends BitmapTransformation {
        private float radius = 0f;

        public GlideRoundTransform(Context context) {
            this(context, 100);
        }

        public GlideRoundTransform(Context context, int dp) {
            super(context);
            this.radius = Resources.getSystem().getDisplayMetrics().density * dp;
        }

        @Override
        protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
            return roundCrop(pool, toTransform);
        }

        private Bitmap roundCrop(BitmapPool pool, Bitmap source) {
            if (source == null) return null;

            Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
            if (result == null) {
                result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
            }
            Canvas canvas = new Canvas(result);
            Paint paint = new Paint();
            paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
            paint.setAntiAlias(true);
            RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
            canvas.drawRoundRect(rectF, radius, radius, paint);
            Log.e("11aa", radius + "");
            return result;
        }

        @Override
        public String getId() {
            return getClass().getName() + Math.round(radius);
        }
    }
        Glide.with(context).load("http://img2.3lian.com/2014/f6/173/d/51.jpg").centerCrop().transform(new GlideRoundTransform(this,50)).animate(animator).into(imageView);

當然如果我們想實現成一個圓形的頭像,只需要在上面基礎上稍微調整即可。那么如何旋轉圖片呢如下

  /**
     *將圖像做旋轉操作
     */
    public class GlideRotateTransform extends BitmapTransformation {
        private float rotateAngle = 0f;

        public GlideRotateTransform(Context context) {
            this(context, 90);
        }

        public GlideRotateTransform(Context context, float rotateAngle) {
            super(context);
            this.rotateAngle = rotateAngle;
        }

        @Override
        protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
            Matrix matrix=new Matrix();
            matrix.postRotate(rotateAngle);
            return Bitmap.createBitmap(toTransform,0,0,toTransform.getWidth(),toTransform.getHeight(),matrix,true);
        }
        @Override
        public String getId() {
            return getClass().getName() + rotateAngle;
        }
    }
        Glide.with(context).load("http://img2.3lian.com/2014/f6/173/d/51.jpg").centerCrop().transform(new GlideRotateTransform(this)).animate(animator).into(imageView);

看到這就明白了,其實自定義轉換也很簡單。需要注意的一點transform()如果多次調用,后面的效果會覆蓋前面的,也就是說我們只能看到最后一次的轉換,所以不要多次調用,還有centerCrop() 和fitCenter() 也是轉換,他是Glide自己實現的轉換。
通過前面幾句的描述,你可能會問既然transform()或者centerCrop() 和fitCenter() 不能多次調用,那么我們想實現多種效果該怎么辦呢?不要驚慌,我們看下transform源碼它就收任意長的參數

 public DrawableRequestBuilder<ModelType> transform(BitmapTransformation... transformations) {
        return bitmapTransform(transformations);
    }

現在我們要實現上面兩個圓角加旋轉的轉換只需要將兩個對象都以參數傳遞就可以了

        Glide.with(context).load("http://img2.3lian.com/2014/f6/173/d/51.jpg").centerCrop().transform(new GlideRoundTransform(this,50),new GlideRotateTransform(this)).animate(animator).into(imageView);

實現效果


這里寫圖片描述

Notifications加載網絡圖片

我們發現現在很多App通知都會有一個圖片展示,這更美觀而且更能形象的表達出通知的內容,那么怎么加載網絡上的圖片到通知欄呢?Glide提供了NotificationTarget來加載網絡上的圖片,當然我們自己寫通知加載網絡上的圖片也能實現,但是畢竟需要耗很多時間,
接下來我們先布局通知UI,如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="2dp">

        <ImageView
            android:id="@+id/notification_icon"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_marginRight="2dp"
            android:layout_weight="0"
            android:scaleType="centerCrop" />

        <TextView
            android:layout_gravity="center"
            android:id="@+id/notification_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ellipsize="end"
            android:singleLine="true"
            android:textSize="12sp" />
    </LinearLayout>
</LinearLayout>

創建自定義通知

  /**
     * 設置通知欄網絡圖標
     */
    private void notificationTarget() {
        RemoteViews remoteViews = new RemoteViews(this.getPackageName(), R.layout.notifition);
        remoteViews.setImageViewResource(R.id.notification_icon, R.mipmap.ic_launcher);
        remoteViews.setTextViewText(R.id.notification_text, "HeadLine");

        //build notifition
        NotificationCompat.Builder builder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("Content Title")
                .setContentText("Content Text")
                .setContent(remoteViews)
                .setPriority(NotificationCompat.PRIORITY_MIN);
        final Notification notification=builder.build();
        if (Build.VERSION.SDK_INT>=16){
            notification.bigContentView=remoteViews;
        }
        NotificationManager notificationManager=(NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(NOTIFICATION_ID,notification);

        NotificationTarget notificationTarget=new NotificationTarget(this,remoteViews,R.id.notification_icon,notification,NOTIFICATION_ID);
        Glide.with(this).load(urls[4]).asBitmap().placeholder(R.mipmap.ic_launcher).error(R.mipmap.place).listener(new RequestListener<String, Bitmap>() {
            @Override
            public boolean onException(Exception e, String model, Target<Bitmap> target, boolean isFirstResource) {
                Log.e("TAG",e.toString());
                return true;
            }

            @Override
            public boolean onResourceReady(Bitmap resource, String model, Target<Bitmap> target, boolean isFromMemoryCache, boolean isFirstResource) {
                Log.e("TAG","1111111111111111111");
                return false;
            }
        }) .dontAnimate().into(notificationTarget);

    }

自定義GlideModule

我們先新建一個類實現GlideModule接口 ,在applyOptions方法里利用GlideBuilder 全局改變 Glide 行為的一個方式,通過全局GlideModule 配置Glide,用GlideBuilder設置選項,用Glide注冊ModelLoader等

/**
 * Created by xiehui on 2016/8/29.
 */
public class ConfigurationGlide implements GlideModule {
    @Override
    public void applyOptions(final Context context, GlideBuilder builder) {
    //配置
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
    }
}

完成自定義類的創建后,需要在清單文件中配置,如果不配置的話,我們自定義的ConfigurationGlide 里實現的內容都不會生效。

    <meta-data android:name="com.example.xh.glidedemo.ConfigurationGlide"
        android:value="GlideModule"/>

混淆

因為要用到反射的GlideModule可以通過反射實例化

-keepnames class com.example.xh.glidedemo.ConfigurationGlide

當然我們最好的方法是一次性混淆配置

-keep public class * implements com.bumptech.glide.module.GlideModule

Glide 的圖片質量

在 Android 中有兩個主要的方法對圖片進行解碼:ARGB8888(每像素4字節存儲) 和 RGB565(每像素2字節存儲)。當然ARGB8888有更高的圖片質量,Glide默認使用RGB565進行解碼,所以內存占用相對較小,如果我們想要更高的圖片質量,可以設置,如下

builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);

內存緩存

Glide提供了一個類MemorySizeCalculator,用于決定內存緩存大小以及 bitmap 的緩存池。bitmap 池維護了你 App 的堆中的圖像分配。正確的 bitmpa 池是非常必要的,因為它避免很多的圖像重復回收,這樣可以確保垃圾回收器的管理更加合理。它的默認計算實現

        //內存緩存
        MemorySizeCalculator memorySizeCalculator = new MemorySizeCalculator(context);
        int defaultMemoryCacheSize = memorySizeCalculator.getMemoryCacheSize();
        int defalutBitmapPoolSize = memorySizeCalculator.getBitmapPoolSize();

此時我們可以根據默認的大小去調整自己想要的大小

        builder.setMemoryCache(new LruResourceCache((int) (defalutBitmapPoolSize * 1.2)));//內部
        builder.setBitmapPool(new LruBitmapPool((int) (defalutBitmapPoolSize * 1.2)));

磁盤緩存

Glide圖片緩存有兩種情況,一種是內部磁盤緩存另一種是外部磁盤緩存。我們可以通過 builder.setDiskCache()設置,并且Glide已經封裝好了兩個類實現外部和內部磁盤緩存,分別是InternalCacheDiskCacheFactory和ExternalCacheDiskCacheFactory,通過源碼發現磁盤緩存默認是250M,路徑名image_manager_disk_cache如下

        //DiskCache接口內部Factory接口聲明

        /** 250 MB of cache. */
        int DEFAULT_DISK_CACHE_SIZE = 250 * 1024 * 1024;
        String DEFAULT_DISK_CACHE_DIR = "image_manager_disk_cache";

設置磁盤緩存大小100M

 //磁盤緩存100M
        builder.setDiskCache(new InternalCacheDiskCacheFactory(context, 1024 * 1024 * 100));//內部磁盤緩存
        builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, 100 * 1024 * 1024));//磁盤緩存到外部存儲

上面我們實現了自定義緩存的大小,但是緩存的路徑是固定的,那么該如何自己定義緩存路徑呢?上代碼

//指定緩存目錄1
        String downLoadPath = Environment.getDownloadCacheDirectory().getPath();
        builder.setDiskCache(new DiskLruCacheFactory(downLoadPath, defaultMemoryCacheSize));
        //指定緩存目錄2
        builder.setDiskCache(new DiskCache.Factory() {
            @Override
            public DiskCache build() {
                File cacheLocation = new File(context.getExternalCacheDir(), "cache_dir");
                cacheLocation.mkdirs();

                return DiskLruCacheWrapper.get(cacheLocation, 1024 * 1024 * 100);
            }
        });

registerComponents里的實現參考源碼

本文是自己學習的一個總結記錄,同時也希望對看本文的你有一定幫助,由于水平有限,文中若有錯誤的地方歡迎指正!謝謝。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容