天天看點

glide加載圖檔閃爍_Android Glide圖檔加載架構介紹

glide加載圖檔閃爍_Android Glide圖檔加載架構介紹

官方介紹

Glide是一個快速高效的Android圖檔加載庫,注重于平滑的滾動。Glide提供了易用的API,高性能、可擴充的圖檔解碼管道(decode pipeline),以及自動的資源池技術。

Glide 支援拉取,解碼和展示視訊快照,圖檔,和GIF動畫。Glide的Api是如此的靈活,開發者甚至可以插入和替換成自己喜愛的任何網絡棧。預設情況下,Glide使用的是一個定制化的基于HttpUrlConnection的棧,但同時也提供了與Google Volley和Square OkHttp快速內建的工具庫。

雖然Glide 的主要目标是讓任何形式的圖檔清單的滾動盡可能地變得更快、更平滑,但實際上,Glide幾乎能滿足你對遠端圖檔的拉取/縮放/顯示的一切需求。

簡單用法

Glide.with(fragment)    .load(url)    .into(imageView);
           

關于性能的介紹

Glide 充分考慮了Android圖檔加載性能的兩個關鍵方面:

  • 圖檔解碼速度
  • 解碼圖檔帶來的資源壓力

為了讓使用者擁有良好的App使用體驗,圖檔不僅要快速加載,而且還不能因為過多的主線程I/O或頻繁的垃圾回收導緻頁面的閃爍和抖動現象。

Glide使用了多個步驟來確定在Android上加載圖檔盡可能的快速和平滑:

  • 自動、智能地下采樣(downsampling)和緩存(caching),以最小化存儲開銷和解碼次數;
  • 積極的資源重用,例如位元組數組和Bitmap,以最小化昂貴的垃圾回收和堆碎片影響;
  • 深度的生命周期內建,以確定僅優先處理活躍的Fragment和Activity的請求,并有利于應用在必要時釋放資源以避免在背景時被殺掉。

對Glide加載架構進行自己的封裝

public class GlideUtil {    public static final String TAG = "GlideUtil";    /**     * Glide的請求管理器類     */    private static RequestManager mRequestManager;    private static Context mContext;    /**     * 初始化Glide工具     *     * @param context     */    public static void init(Context context) {        mContext = context;        mRequestManager = Glide.with(context);    }    /**     * Glide工具類是否已經初始化     *     * @return 已初始化則傳回true     */    public static boolean isInit() {        if (mContext == null || mRequestManager == null) {            Log.i(TAG, TAG + "not initComponent");            return false;        }        return true;    }    /**     * 加載圖檔的基礎方法     *     * @param url     * @param imageView     * @param isCache     * @param shapeType     * @param defaultImg     */    public static void loadPicture(Object url, ImageView imageView, boolean isCache, int scaleType, int shapeType, @DrawableRes int defaultImg) {        if (!isInit()) {            return;        }        RequestOptions options = new RequestOptions();        if (scaleType == BaseConstant.GLIDE_SCALE_TYPE_CENTER_CROP) {            options.centerCrop();        } else if (scaleType == BaseConstant.GLIDE_SCALE_TYPE_FIT_CENTER) {            options.fitCenter();        }        if (shapeType == BaseConstant.GLIDE_SHAPE_TYPE_CIRCLE) {            options = RequestOptions.bitmapTransform(new CircleCrop());        }        if (isCache) {            options.diskCacheStrategy(DiskCacheStrategy.RESOURCE);        } else {            options.diskCacheStrategy(DiskCacheStrategy.NONE);        }        if (defaultImg != -1) {            options.placeholder(defaultImg);        }        options.dontAnimate();        mRequestManager                .load(url)                .apply(options).into(imageView);    }    /**     * 加載正方形的網絡圖檔     *     * @param url       網絡位址     * @param imageView 目标控件     */    public static void loadPicture(String url, ImageView imageView) {        loadPicture(url, imageView, true, BaseConstant.GLIDE_SCALE_TYPE_NULL, BaseConstant.GLIDE_SHAPE_TYPE_SQUARE, -1);    }    /**     * 跳過緩存加載圖檔     *     * @param url     * @param imageView     */    public static void loadPictureSkipMemory(String url, ImageView imageView) {        loadPicture(url, imageView, false, BaseConstant.GLIDE_SCALE_TYPE_NULL, BaseConstant.GLIDE_SHAPE_TYPE_SQUARE, -1);    }    /**     * 加載方形的圖檔 圖檔剪裁方式fitCenter     *     * @param url     * @param imageView     * @param defaultImg     */    public static void loadPictureFitCenter(String url, ImageView imageView, @DrawableRes int defaultImg) {        loadPicture(url, imageView, true, BaseConstant.GLIDE_SCALE_TYPE_FIT_CENTER, BaseConstant.GLIDE_SHAPE_TYPE_SQUARE, defaultImg);    }    public static void loadPictureFitCenter(String url, ImageView imageView) {        loadPicture(url, imageView, true, BaseConstant.GLIDE_SCALE_TYPE_FIT_CENTER, BaseConstant.GLIDE_SHAPE_TYPE_SQUARE, -1);    }    /**     * 加載方形的圖檔   圖檔剪裁方式CenterCrop     *     * @param url     * @param imageView     * @param defaultImg     */    public static void loadPictureCenterCrop(String url, ImageView imageView, @DrawableRes int defaultImg) {        loadPicture(url, imageView, true, BaseConstant.GLIDE_SCALE_TYPE_CENTER_CROP, BaseConstant.GLIDE_SHAPE_TYPE_SQUARE, defaultImg);    }    public static void loadPictureCenterCrop(String url, ImageView imageView) {        loadPicture(url, imageView, true, BaseConstant.GLIDE_SCALE_TYPE_CENTER_CROP, BaseConstant.GLIDE_SHAPE_TYPE_SQUARE, -1);    }    /**     * 加載圓形的網絡圖檔     *     * @param url       網絡位址     * @param imageView 目标控件     */    public static void loadCirclePicture(String url, ImageView imageView) {        loadPicture(url, imageView, true, BaseConstant.GLIDE_SCALE_TYPE_CENTER_CROP, BaseConstant.GLIDE_SHAPE_TYPE_CIRCLE, -1);    }    /**     * 加載圓形的網絡圖檔     *     * @param url        網絡位址     * @param imageView  目标控件     * @param defaultImg 預設的圖檔 若不需要則輸入-1     */    public static void loadCirclePicture(String url, ImageView imageView, @DrawableRes int defaultImg) {        loadPicture(url, imageView, true, BaseConstant.GLIDE_SCALE_TYPE_NULL, BaseConstant.GLIDE_SHAPE_TYPE_CIRCLE, defaultImg);    }    /**     * 加載資源圖檔檔案     *     * @param resId     * @param imageView     */    public static void loadDrawableRes(@DrawableRes int resId, ImageView imageView) {        loadPicture(resId, imageView, true, BaseConstant.GLIDE_SCALE_TYPE_CENTER_CROP, BaseConstant.GLIDE_SHAPE_TYPE_SQUARE, -1);    }}
           

舊版的Glide加載圓形或者圓角圖檔是需要自己定義轉換方法的

例如,圓形的轉換類GlideCircleTransform

public class GlideCircleTransform extends BitmapTransformation {    public GlideCircleTransform() {    }    private static Bitmap circleCrop(BitmapPool pool, Bitmap source) {        if (source == null) return null;        int size = Math.min(source.getWidth(), source.getHeight());        int x = (source.getWidth() - size) / 2;        int y = (source.getHeight() - size) / 2;        Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);        Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);        if (result == null) {            result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);        }        Canvas canvas = new Canvas(result);        Paint paint = new Paint();        paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));        paint.setAntiAlias(true);        float r = size / 2f;        canvas.drawCircle(r, r, r, paint);        return result;    }    @Override    public void updateDiskCacheKey(MessageDigest messageDigest) {    }    @Override    protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {        return circleCrop(pool, toTransform);    }}
           

圓角轉換類GlideRoundTransform

public class GlideRoundTransform extends BitmapTransformation {    private static float radius = 0f;    public GlideRoundTransform() {        this(4);    }    public GlideRoundTransform(int dp) {        super();        this.radius = Resources.getSystem().getDisplayMetrics().density * dp;    }    @Override    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {        return roundCrop(pool, toTransform);    }    private static 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);        return result;    }    @Override    public void updateDiskCacheKey(MessageDigest messageDigest) {    }}
           

但在新版的Glide中以及提供了基礎類CircleCrop進行代替,可以直接用CircleCrop進行圓形圖檔的加載

自己封裝的工具類的使用方法

在Application類中進行工具類的初始化

public class StandardApp extends FrameApplication {    @Override    public void onCreate() {        super.onCreate();        ...        //初始化圖檔加載架構        GlideUtil.init(getApplicationContext());      ...    }}
           

然後在需要加載圖檔的地方

GlideUtil.loadPicture(“圖檔連結”, [圖檔控件]);
           

開發準則,把重複的部分封裝起來,讓代碼更加簡潔明了。