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:roundIcon="@mipmap/ic_launcher"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme"
tools:ignore="AllowBackup,GoogleAppIndexingWarning">

View File

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

View File

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

View File

@ -1,7 +1,9 @@
package io.noties.markwon.image.glide;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Spanned;
import android.widget.TextView;
@ -11,6 +13,7 @@ import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
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.Target;
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.ImageSpanFactory;
/**
* @since 4.0.0
*/
/**
* @since 4.0.0
*/
@ -39,15 +46,37 @@ public class GlideImagesPlugin extends AbstractMarkwonPlugin {
@NonNull
RequestBuilder<Drawable> load(@NonNull AsyncDrawable drawable);
RequestBuilder<GifDrawable> loadGif(@NonNull AsyncDrawable drawable);
void cancel(@NonNull Target<?> target);
}
@NonNull
public static GlideImagesPlugin create(@NonNull final Context context) {
// @since 4.5.0 cache RequestManager
// sometimes `cancel` would be called after activity is destroyed,
// so `Glide.with(context)` will throw an exception
return create(Glide.with(context));
return create(new GlideStore() {
@NonNull
@Override
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
@ -59,6 +88,11 @@ public class GlideImagesPlugin extends AbstractMarkwonPlugin {
return requestManager.load(drawable.getDestination());
}
@Override
public RequestBuilder<GifDrawable> loadGif(@NonNull AsyncDrawable drawable) {
return requestManager.asGif().load(drawable.getDestination());
}
@Override
public void cancel(@NonNull Target<?> target) {
requestManager.clear(target);
@ -98,10 +132,22 @@ public class GlideImagesPlugin extends AbstractMarkwonPlugin {
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 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) {
this.glideStore = glideStore;
@ -109,17 +155,32 @@ public class GlideImagesPlugin extends AbstractMarkwonPlugin {
@Override
public void load(@NonNull AsyncDrawable drawable) {
String dest = drawable.getDestination();
if (dest.contains(".gif")){
final Target<GifDrawable> targetGif = new AsyncGifDrawableTarget(drawable);
if (!cache.containsKey(dest)){
cache.put(dest, targetGif);
glideStore.loadGif(drawable)
.into(targetGif);
}
} else {
final Target<Drawable> target = new AsyncDrawableTarget(drawable);
cache.put(drawable, target);
if (!cache.containsKey(dest)){
cache.put(dest, target);
glideStore.load(drawable)
.into(target);
}
}
}
@Override
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) {
glideStore.cancel(target);
cache.remove(dest);
}
}
@ -139,7 +200,8 @@ public class GlideImagesPlugin extends AbstractMarkwonPlugin {
@Override
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()) {
DrawableUtils.applyIntrinsicBoundsIfEmpty(resource);
drawable.setResult(resource);
@ -158,12 +220,69 @@ public class GlideImagesPlugin extends AbstractMarkwonPlugin {
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
if (cache.remove(drawable) != null) {
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 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();
}
}
}