Glide接入

1、Glide的生命周期绑定

Glide.with()方法可以传入Context、Activity、Fragment等类型参数,Glide会根据传入参数的不同绑定不同的生命周期。因此,如果没有特定的需求,尽量传入Activity或者Fragment参数,这样Glide请求会在合适的时机释放资源。值得注意的是,如果在非主线程下,不管传入什么参数,Glide默认会取ApplicationContext。

@NonNull
public static RequestManager with(@NonNull Context context) {
    return getRetriever(context).get(context);
}

@NonNull
public static RequestManager with(@NonNull Activity activity) {
    return getRetriever(activity).get(activity);
}

@NonNull
public static RequestManager with(@NonNull FragmentActivity activity) {
    return getRetriever(activity).get(activity);
}

@NonNull
public static RequestManager with(@NonNull Fragment fragment) {
    return getRetriever(fragment.getActivity()).get(fragment);
}

@NonNull
public static RequestManager with(@NonNull android.support.v4.app.Fragment fragment) {
    return getRetriever(fragment.getActivity()).get(fragment);
}

@NonNull
public static RequestManager with(@NonNull View view) {
    return getRetriever(view.getContext()).get(view);
}


...


@NonNull
public RequestManager get(@NonNull Activity activity) {
    if(Util.isOnBackgroundThread()) {
        return this.get(activity.getApplicationContext());
    } else {
        assertNotDestroyed(activity);
        FragmentManager fm = activity.getFragmentManager();
        return this.fragmentGet(activity, fm, (android.app.Fragment)null);
    }
}

2、Glide的clearMemory和trimMemory

在接其他图片框架时,通常在Application中,我们可以做这样优化,及时回收图片缓存。

@Override
public void onTrimMemory(int level) {
    super.onTrimMemory(level);
    try {
        ImageDisplayUtil.clearMemoryCache(this);
        Debug.d(TAG, "onTrimMemory level: " + level + " clear Image Loader Cache");
    } catch (Throwable e) {
        Debug.w(e.getMessage());
    }
}

@Override
public void onLowMemory() {
    super.onLowMemory();
    ImageDisplayUtil.clearMemoryCache(this);
}

但是,查看源码我们可以发现Glide初始化时注册了ComponentCallbacks2回调,其实已经帮我们做好了这部分操作,无需我们再去处理。

private static void initializeGlide(@NonNull Context context, @NonNull GlideBuilder builder) {
    Context applicationContext = context.getApplicationContext();
    ...
    applicationContext.registerComponentCallbacks(glide);
    glide = glide;
}


public void clearMemory() {
    Util.assertMainThread();
    this.memoryCache.clearMemory();
    this.bitmapPool.clearMemory();
    this.arrayPool.clearMemory();
}

public void trimMemory(int level) {
    Util.assertMainThread();
    this.memoryCache.trimMemory(level);
    this.bitmapPool.trimMemory(level);
    this.arrayPool.trimMemory(level);
}


public void onTrimMemory(int level) {
    this.trimMemory(level);
}

public void onLowMemory() {
    this.clearMemory();
}

3、RoundedImageView加载gif图片失效

RoundedImageView重写了setImageDrawable等方法,最终转换成RoundedDrawable,导致Glide加载gif得到的GifDrawable被也被转换成RoundedDrawable,因此失去了gif效果,只能显示第一帧。

@Override
  public void setImageDrawable(Drawable drawable) {
    mResource = 0;
    mDrawable = RoundedDrawable.fromDrawable(drawable);
    updateDrawableAttrs();
    super.setImageDrawable(mDrawable);
  }

  @Override
  public void setImageBitmap(Bitmap bm) {
    mResource = 0;
    mDrawable = RoundedDrawable.fromBitmap(bm);
    updateDrawableAttrs();
    super.setImageDrawable(mDrawable);
  }

  @Override
  public void setImageResource(@DrawableRes int resId) {
    if (mResource != resId) {
      mResource = resId;
      mDrawable = resolveResource();
      updateDrawableAttrs();
      super.setImageDrawable(mDrawable);
    }
  }

  @Override public void setImageURI(Uri uri) {
    super.setImageURI(uri);
    setImageDrawable(getDrawable());
  }

4、警惕setTag方法

Glide在图片请求时会将request对象设置到ViewTarget的view(通常是imageview)的tag中,为了防止request对象被篡改,Glide设置了request异常检查。

public void setRequest(@Nullable Request request) {
        this.setTag(request);
    }

    @Nullable
    public Request getRequest() {
        Object tag = this.getTag();
        Request request = null;
        if(tag != null) {
            if(!(tag instanceof Request)) {
                throw new IllegalArgumentException("You must not call setTag() on a view Glide is targeting");
            }

            request = (Request)tag;
        }

        return request;
    }

    private void setTag(@Nullable Object tag) {
        if(tagId == null) {
            isTagUsedAtLeastOnce = true;
            this.view.setTag(tag);
        } else {
            this.view.setTag(tagId.intValue(), tag);
        }

    }

    @Nullable
    private Object getTag() {
        return tagId == null?this.view.getTag():this.view.getTag(tagId.intValue());
    }

如果一定要设置tag,可以考虑给ViewTarget事先统一设置tagId。从上述源码可以看出,如果tagId不等于null,request会存到这个特定tagId key对应的tag value中去,后续设置tag时,只要不覆盖tagId对应的value即可。

你可能感兴趣的:(Android开发)