diff --git a/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java b/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java index d3e0d8984..8bd6de164 100644 --- a/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java +++ b/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java @@ -1681,7 +1681,6 @@ public final class SpiderQueen implements Runnable { image = Image.decode(((FileInputStream) is).getFD(), true); } catch (IOException e) { e.printStackTrace(); - image = null; } finally { try { is.close(); diff --git a/app/src/main/java/com/hippo/glgallery/GalleryProvider.java b/app/src/main/java/com/hippo/glgallery/GalleryProvider.java index 63852ec3e..0bf068875 100644 --- a/app/src/main/java/com/hippo/glgallery/GalleryProvider.java +++ b/app/src/main/java/com/hippo/glgallery/GalleryProvider.java @@ -57,6 +57,7 @@ public abstract class GalleryProvider { public void stop() { OSUtils.checkMainLoop(); mImageCache.evictAll(); + Image.lazyEvictAll(); } public void setGLRoot(GLRoot glRoot) { @@ -245,18 +246,14 @@ public abstract class GalleryProvider { } public void add(Integer key, ImageWrapper value) { - if (value.getFormat() != Image.FORMAT_ANIMATED && value.obtain()) { - put(key, value); - } + if (value.getFormat() != Image.FORMAT_ANIMATED) + if (value.obtain()) + put(key, value); } @Override protected int sizeOf(Integer key, ImageWrapper value) { - int size = value.getWidth() * value.getHeight() * 4; - if (value.getFormat() == Image.FORMAT_ANIMATED) { - size *= 5; - } - return size; + return value.getWidth() * value.getHeight() * 4; } @Override diff --git a/native/src/main/java/com/hippo/image/Image.java b/native/src/main/java/com/hippo/image/Image.java index beb3236e9..0cf56e2f5 100644 --- a/native/src/main/java/com/hippo/image/Image.java +++ b/native/src/main/java/com/hippo/image/Image.java @@ -17,11 +17,12 @@ package com.hippo.image; import android.graphics.Bitmap; +import android.util.Log; import androidx.annotation.Nullable; import java.io.FileDescriptor; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.ArrayList; /** * The {@code Image} is a image which stored pixel data in native heap @@ -31,7 +32,9 @@ public final class Image { public static final int FORMAT_ANIMATED = 1; - private static final AtomicInteger sImageCount = new AtomicInteger(); + private static final ArrayList imageList = new ArrayList<>(); + private static boolean needEvictAll = false; + private final int mFormat; private final int mWidth; private final int mHeight; @@ -39,12 +42,27 @@ public final class Image { private Throwable mRecycleTracker; private Image(long nativePtr, int format, int width, int height) { + if (needEvictAll) + evictAll(); mNativePtr = nativePtr; mFormat = format; mWidth = width; mHeight = height; - sImageCount.getAndIncrement(); + imageList.add(this); + } + + public static void lazyEvictAll() { + needEvictAll = true; + } + + private static void evictAll() { + for (Image image : imageList) { + nativeRecycle(image.mNativePtr); + image.mNativePtr = 0; + } + imageList.clear(); + needEvictAll = false; } /** @@ -84,7 +102,7 @@ public final class Image { * It is useful for debug. */ public static int getImageCount() { - return sImageCount.get(); + return imageList.size(); } private static native Image nativeDecode(FileDescriptor fd); @@ -194,7 +212,7 @@ public final class Image { nativeRecycle(mNativePtr); mNativePtr = 0; - sImageCount.getAndDecrement(); + imageList.remove(this); mRecycleTracker = new Throwable("It's a ImageRecycleTracker"); }