Update glide image plugin

This commit is contained in:
chengjunzhang61 2021-12-09 05:21:36 -08:00
parent 687c67a12b
commit a5f9628265
4 changed files with 144 additions and 12 deletions

View File

@ -12,6 +12,7 @@
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true" android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme" android:theme="@style/AppTheme"
tools:ignore="AllowBackup,GoogleAppIndexingWarning"> tools:ignore="AllowBackup,GoogleAppIndexingWarning">

View File

@ -11,6 +11,7 @@ import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.RequestManager; import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.DataSource; import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException; import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.gif.GifDrawable;
import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.target.Target;
@ -76,6 +77,11 @@ public class GlideGifImageSample extends MarkwonTextViewSample {
.load(destination); .load(destination);
} }
@Override
public RequestBuilder<GifDrawable> loadGif(@NonNull AsyncDrawable drawable) {
return null;
}
@Override @Override
public void cancel(@NonNull Target<?> target) { public void cancel(@NonNull Target<?> target) {
requestManager.clear(target); requestManager.clear(target);

View File

@ -7,6 +7,7 @@ import androidx.annotation.NonNull;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder; import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.resource.gif.GifDrawable;
import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.target.Target;
import io.noties.markwon.Markwon; import io.noties.markwon.Markwon;
@ -45,6 +46,11 @@ public class GlidePlaceholderImageSample extends MarkwonTextViewSample {
.placeholder(R.drawable.ic_home_black_36dp); .placeholder(R.drawable.ic_home_black_36dp);
} }
@Override
public RequestBuilder<GifDrawable> loadGif(@NonNull AsyncDrawable drawable) {
return null;
}
@Override @Override
public void cancel(@NonNull Target<?> target) { public void cancel(@NonNull Target<?> target) {
Glide.with(context) Glide.with(context)

View File

@ -1,7 +1,9 @@
package io.noties.markwon.image.glide; package io.noties.markwon.image.glide;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Spanned; import android.text.Spanned;
import android.widget.TextView; import android.widget.TextView;
@ -11,6 +13,7 @@ import androidx.annotation.Nullable;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder; import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.RequestManager; import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.resource.gif.GifDrawable;
import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition; import com.bumptech.glide.request.transition.Transition;
@ -29,6 +32,10 @@ import io.noties.markwon.image.AsyncDrawableScheduler;
import io.noties.markwon.image.DrawableUtils; import io.noties.markwon.image.DrawableUtils;
import io.noties.markwon.image.ImageSpanFactory; import io.noties.markwon.image.ImageSpanFactory;
/**
* @since 4.0.0
*/
/** /**
* @since 4.0.0 * @since 4.0.0
*/ */
@ -39,15 +46,37 @@ public class GlideImagesPlugin extends AbstractMarkwonPlugin {
@NonNull @NonNull
RequestBuilder<Drawable> load(@NonNull AsyncDrawable drawable); RequestBuilder<Drawable> load(@NonNull AsyncDrawable drawable);
RequestBuilder<GifDrawable> loadGif(@NonNull AsyncDrawable drawable);
void cancel(@NonNull Target<?> target); void cancel(@NonNull Target<?> target);
} }
@NonNull @NonNull
public static GlideImagesPlugin create(@NonNull final Context context) { public static GlideImagesPlugin create(@NonNull final Context context) {
// @since 4.5.0 cache RequestManager return create(new GlideStore() {
// sometimes `cancel` would be called after activity is destroyed, @NonNull
// so `Glide.with(context)` will throw an exception @Override
return create(Glide.with(context)); public RequestBuilder<Drawable> load(@NonNull AsyncDrawable drawable) {
return Glide.with(getValidContext(context))
.load(drawable.getDestination());
}
@Override
public RequestBuilder<GifDrawable> loadGif(@NonNull AsyncDrawable drawable) {
return Glide.with(getValidContext(context))
.asGif()
.load(drawable.getDestination());
}
@Override
public void cancel(@NonNull Target<?> target) {
if (target != null){
// Fix the sentry issue Canvas: trying to use a recycled bitmap android.graphics.Bitmap@a44a774
// Glide.with(getValidContext(context))
// .clear(target);
}
}
});
} }
@NonNull @NonNull
@ -59,6 +88,11 @@ public class GlideImagesPlugin extends AbstractMarkwonPlugin {
return requestManager.load(drawable.getDestination()); return requestManager.load(drawable.getDestination());
} }
@Override
public RequestBuilder<GifDrawable> loadGif(@NonNull AsyncDrawable drawable) {
return requestManager.asGif().load(drawable.getDestination());
}
@Override @Override
public void cancel(@NonNull Target<?> target) { public void cancel(@NonNull Target<?> target) {
requestManager.clear(target); requestManager.clear(target);
@ -98,10 +132,22 @@ public class GlideImagesPlugin extends AbstractMarkwonPlugin {
AsyncDrawableScheduler.schedule(textView); AsyncDrawableScheduler.schedule(textView);
} }
public static Context getValidContext(final Context context) {
if (context instanceof Activity) {
final Activity activity = (Activity) context;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
if (activity.isDestroyed() || activity.isFinishing()) {
return context.getApplicationContext();
}
}
}
return context;
}
private static class GlideAsyncDrawableLoader extends AsyncDrawableLoader { private static class GlideAsyncDrawableLoader extends AsyncDrawableLoader {
private final GlideStore glideStore; private final GlideStore glideStore;
private final Map<AsyncDrawable, Target<?>> cache = new HashMap<>(2); private final Map<String, Target<?>> cache = new HashMap<>(2);
GlideAsyncDrawableLoader(@NonNull GlideStore glideStore) { GlideAsyncDrawableLoader(@NonNull GlideStore glideStore) {
this.glideStore = glideStore; this.glideStore = glideStore;
@ -109,17 +155,32 @@ public class GlideImagesPlugin extends AbstractMarkwonPlugin {
@Override @Override
public void load(@NonNull AsyncDrawable drawable) { public void load(@NonNull AsyncDrawable drawable) {
final Target<Drawable> target = new AsyncDrawableTarget(drawable); String dest = drawable.getDestination();
cache.put(drawable, target); if (dest.contains(".gif")){
glideStore.load(drawable) final Target<GifDrawable> targetGif = new AsyncGifDrawableTarget(drawable);
.into(target); if (!cache.containsKey(dest)){
cache.put(dest, targetGif);
glideStore.loadGif(drawable)
.into(targetGif);
}
} else {
final Target<Drawable> target = new AsyncDrawableTarget(drawable);
if (!cache.containsKey(dest)){
cache.put(dest, target);
glideStore.load(drawable)
.into(target);
}
}
} }
@Override @Override
public void cancel(@NonNull AsyncDrawable drawable) { public void cancel(@NonNull AsyncDrawable drawable) {
final Target<?> target = cache.remove(drawable); String dest = drawable.getDestination();
final Target<?> target = cache.get(dest);
if (target != null) { if (target != null) {
glideStore.cancel(target); glideStore.cancel(target);
cache.remove(dest);
} }
} }
@ -139,7 +200,8 @@ public class GlideImagesPlugin extends AbstractMarkwonPlugin {
@Override @Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
if (cache.remove(drawable) != null) { String dest = drawable.getDestination();
if (cache.get(dest) != null) {
if (drawable.isAttached()) { if (drawable.isAttached()) {
DrawableUtils.applyIntrinsicBoundsIfEmpty(resource); DrawableUtils.applyIntrinsicBoundsIfEmpty(resource);
drawable.setResult(resource); drawable.setResult(resource);
@ -158,12 +220,69 @@ public class GlideImagesPlugin extends AbstractMarkwonPlugin {
@Override @Override
public void onLoadFailed(@Nullable Drawable errorDrawable) { public void onLoadFailed(@Nullable Drawable errorDrawable) {
if (cache.remove(drawable) != null) { String dest = drawable.getDestination();
if (cache.get(dest) != null) {
if (errorDrawable != null if (errorDrawable != null
&& drawable.isAttached()) { && drawable.isAttached()) {
DrawableUtils.applyIntrinsicBoundsIfEmpty(errorDrawable); DrawableUtils.applyIntrinsicBoundsIfEmpty(errorDrawable);
drawable.setResult(errorDrawable); drawable.setResult(errorDrawable);
} }
cache.remove(dest);
}
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
// we won't be checking if target is still present as cancellation
// must remove target anyway
if (drawable.isAttached()) {
drawable.clearResult();
}
}
}
private class AsyncGifDrawableTarget extends CustomTarget<GifDrawable> {
private final AsyncDrawable drawable;
AsyncGifDrawableTarget(@NonNull AsyncDrawable drawable) {
this.drawable = drawable;
}
@Override
public void onLoadStarted(@Nullable Drawable placeholder) {
if (placeholder != null
&& drawable.isAttached()) {
DrawableUtils.applyIntrinsicBoundsIfEmpty(placeholder);
drawable.setResult(placeholder);
}
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
String dest = drawable.getDestination();
if (cache.get(dest) != null) {
if (errorDrawable != null
&& drawable.isAttached()) {
DrawableUtils.applyIntrinsicBoundsIfEmpty(errorDrawable);
drawable.setResult(errorDrawable);
}
cache.remove(dest);
}
}
@Override
public void onResourceReady(@NonNull GifDrawable resource, @Nullable Transition<? super GifDrawable> transition) {
String dest = drawable.getDestination();
if (cache.get(dest) != null) {
if (drawable.isAttached()) {
DrawableUtils.applyIntrinsicBoundsIfEmpty(resource);
drawable.setResult(resource);
}
if (resource != null) {
resource.start();
}
} }
} }