From feb9bbadc6b45f03e2725e9b5c079ab9a920b1b6 Mon Sep 17 00:00:00 2001 From: seven332 Date: Sun, 28 Feb 2016 15:39:21 +0800 Subject: [PATCH] Add GalleryProvider.cancelRequest(int), fix SpiderQueen.request(int, boolean) --- .../ehviewer/download/DownloadService.java | 1 + .../ehviewer/gallery/DirGalleryProvider.java | 20 ++- .../ehviewer/gallery/EhGalleryProvider.java | 7 + .../ehviewer/gallery/GalleryProvider.java | 2 + .../ehviewer/gallery/ZipGalleryProvider.java | 20 ++- .../ehviewer/gallery/gl/GalleryView.java | 4 +- .../hippo/ehviewer/spider/SpiderQueen.java | 140 +++++++++++------- .../hippo/ehviewer/ui/GalleryActivity.java | 5 +- .../ui/scene/GalleryPreviewsScene.java | 6 +- 9 files changed, 144 insertions(+), 61 deletions(-) diff --git a/app/src/main/java/com/hippo/ehviewer/download/DownloadService.java b/app/src/main/java/com/hippo/ehviewer/download/DownloadService.java index 3fc346fe7..3abf7ce3b 100644 --- a/app/src/main/java/com/hippo/ehviewer/download/DownloadService.java +++ b/app/src/main/java/com/hippo/ehviewer/download/DownloadService.java @@ -41,6 +41,7 @@ import com.hippo.yorozuya.SimpleHandler; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +// TODO Stop and delete action should not pass through DownloadService public class DownloadService extends Service implements DownloadManager.DownloadListener { public static final String ACTION_START = "start"; diff --git a/app/src/main/java/com/hippo/ehviewer/gallery/DirGalleryProvider.java b/app/src/main/java/com/hippo/ehviewer/gallery/DirGalleryProvider.java index 120c4d458..8ebbb010d 100644 --- a/app/src/main/java/com/hippo/ehviewer/gallery/DirGalleryProvider.java +++ b/app/src/main/java/com/hippo/ehviewer/gallery/DirGalleryProvider.java @@ -22,6 +22,7 @@ import android.util.Log; import com.hippo.ehviewer.GetText; import com.hippo.ehviewer.R; +import com.hippo.ehviewer.gallery.gl.GalleryPageView; import com.hippo.image.Image; import com.hippo.yorozuya.PriorityThread; import com.hippo.yorozuya.StringUtils; @@ -42,6 +43,7 @@ public class DirGalleryProvider extends GalleryProvider implements Runnable { private final File mDir; private final Stack mRequests = new Stack<>(); + private final AtomicInteger mDecodingIndex = new AtomicInteger(GalleryPageView.INVALID_INDEX); @Nullable private Thread mBgThread; private volatile int mSize = STATE_WAIT; @@ -78,12 +80,21 @@ public class DirGalleryProvider extends GalleryProvider implements Runnable { @Override public void request(int index) { synchronized (mRequests) { - mRequests.add(index); - mRequests.notify(); + if (!mRequests.contains(index) && index != mDecodingIndex.get()) { + mRequests.add(index); + mRequests.notify(); + } } notifyPageWait(index); } + @Override + public void cancelRequest(int index) { + synchronized (mRequests) { + mRequests.remove(Integer.valueOf(index)); + } + } + @Override public String getError() { return mError; @@ -125,10 +136,12 @@ public class DirGalleryProvider extends GalleryProvider implements Runnable { continue; } index = mRequests.pop(); + mDecodingIndex.lazySet(index); } // Check index valid if (index < 0 || index >= files.length) { + mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX); notifyPageFailed(index, GetText.getString(R.string.error_out_of_range)); continue; } @@ -136,14 +149,17 @@ public class DirGalleryProvider extends GalleryProvider implements Runnable { try { InputStream is = new FileInputStream(new File(mDir, files[index])); Image image = Image.decode(is, false); + mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX); if (image != null) { notifyPageSucceed(index, image); } else { notifyPageFailed(index, GetText.getString(R.string.error_decoding_failed)); } } catch (FileNotFoundException e) { + mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX); notifyPageFailed(index, GetText.getString(R.string.error_not_found)); } + mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX); } Log.i(TAG, "ImageDecoder end"); diff --git a/app/src/main/java/com/hippo/ehviewer/gallery/EhGalleryProvider.java b/app/src/main/java/com/hippo/ehviewer/gallery/EhGalleryProvider.java index 5e55cef30..12809aff2 100644 --- a/app/src/main/java/com/hippo/ehviewer/gallery/EhGalleryProvider.java +++ b/app/src/main/java/com/hippo/ehviewer/gallery/EhGalleryProvider.java @@ -99,6 +99,13 @@ public class EhGalleryProvider extends GalleryProvider implements SpiderQueen.On } } + @Override + public void cancelRequest(int index) { + if (mSpiderQueen != null) { + mSpiderQueen.cancelRequest(index); + } + } + @Override public String getError() { if (mSpiderQueen != null) { diff --git a/app/src/main/java/com/hippo/ehviewer/gallery/GalleryProvider.java b/app/src/main/java/com/hippo/ehviewer/gallery/GalleryProvider.java index bfd8c6d32..f4f8611be 100644 --- a/app/src/main/java/com/hippo/ehviewer/gallery/GalleryProvider.java +++ b/app/src/main/java/com/hippo/ehviewer/gallery/GalleryProvider.java @@ -78,6 +78,8 @@ public abstract class GalleryProvider { request(index); } + public abstract void cancelRequest(int index); + public abstract String getError(); public void setGalleryProviderListener(GalleryProviderListener listener) { diff --git a/app/src/main/java/com/hippo/ehviewer/gallery/ZipGalleryProvider.java b/app/src/main/java/com/hippo/ehviewer/gallery/ZipGalleryProvider.java index 53b4121d1..1d9f8e345 100644 --- a/app/src/main/java/com/hippo/ehviewer/gallery/ZipGalleryProvider.java +++ b/app/src/main/java/com/hippo/ehviewer/gallery/ZipGalleryProvider.java @@ -22,6 +22,7 @@ import android.util.Log; import com.hippo.ehviewer.GetText; import com.hippo.ehviewer.R; +import com.hippo.ehviewer.gallery.gl.GalleryPageView; import com.hippo.image.Image; import com.hippo.yorozuya.PriorityThread; import com.hippo.yorozuya.StringUtils; @@ -47,6 +48,7 @@ public class ZipGalleryProvider extends GalleryProvider implements Runnable { private final File mFile; private final Stack mRequests = new Stack<>(); + private final AtomicInteger mDecodingIndex = new AtomicInteger(GalleryPageView.INVALID_INDEX); @Nullable private Thread mBgThread; private volatile int mSize = STATE_WAIT; @@ -83,12 +85,21 @@ public class ZipGalleryProvider extends GalleryProvider implements Runnable { @Override public void request(int index) { synchronized (mRequests) { - mRequests.add(index); - mRequests.notify(); + if (!mRequests.contains(index) && index != mDecodingIndex.get()) { + mRequests.add(index); + mRequests.notify(); + } } notifyPageWait(index); } + @Override + public void cancelRequest(int index) { + synchronized (mRequests) { + mRequests.remove(Integer.valueOf(index)); + } + } + @Override public String getError() { return mError; @@ -150,10 +161,12 @@ public class ZipGalleryProvider extends GalleryProvider implements Runnable { continue; } index = mRequests.pop(); + mDecodingIndex.lazySet(index); } // Check index valid if (index < 0 || index >= filenames.size()) { + mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX); notifyPageFailed(index, GetText.getString(R.string.error_out_of_range)); continue; } @@ -163,15 +176,18 @@ public class ZipGalleryProvider extends GalleryProvider implements Runnable { if (zipEntry != null) { InputStream is = zipFile.getInputStream(zipEntry); Image image = Image.decode(is, false); + mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX); if (image != null) { notifyPageSucceed(index, image); } else { notifyPageFailed(index, GetText.getString(R.string.error_decoding_failed)); } } else { + mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX); notifyPageFailed(index, GetText.getString(R.string.error_reading_failed)); } } catch (IOException e) { + mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX); notifyPageFailed(index, GetText.getString(R.string.error_reading_failed)); } } diff --git a/app/src/main/java/com/hippo/ehviewer/gallery/gl/GalleryView.java b/app/src/main/java/com/hippo/ehviewer/gallery/gl/GalleryView.java index a05b48a5f..812b4a37a 100644 --- a/app/src/main/java/com/hippo/ehviewer/gallery/gl/GalleryView.java +++ b/app/src/main/java/com/hippo/ehviewer/gallery/gl/GalleryView.java @@ -855,13 +855,13 @@ public class GalleryView extends GLView implements GestureRecognizer.Listener { } public void unbind(GalleryPageView view) { - onUnbind(view); + onUnbind(view, view.getIndex()); view.setIndex(GalleryPageView.INVALID_INDEX); } public abstract void onBind(GalleryPageView view, int index); - public abstract void onUnbind(GalleryPageView view); + public abstract void onUnbind(GalleryPageView view, int index); /** * @return Null for no error 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 b270456ee..4fed641fd 100644 --- a/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java +++ b/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java @@ -130,7 +130,7 @@ public class SpiderQueen implements Runnable { @Nullable private Thread mDecoderThread; private final Stack mDecodeRequestStack = new Stack<>(); - private final AtomicInteger mDecodeIndex = new AtomicInteger(GalleryPageView.INVALID_INDEX); + private final AtomicInteger mDecodingIndex = new AtomicInteger(GalleryPageView.INVALID_INDEX); private volatile Thread[] mWorkers; private final Object mWorkerLock = new Object(); @@ -398,6 +398,43 @@ public class SpiderQueen implements Runnable { return request(index, false); } + private int getPageState(int index) { + synchronized (mPageStateLock) { + if (mPageStateArray != null && index >= 0 && index < mPageStateArray.length) { + return mPageStateArray[index]; + } else { + return STATE_NONE; + } + } + } + + private void tryToEnsureWorkers() { + boolean startWorkers = false; + synchronized (mRequestPageQueue) { + if (mPageStateArray != null && + (!mForceRequestPageQueue.isEmpty() || + !mRequestPageQueue.isEmpty() || + !mRequestPageQueue2.isEmpty() || + mDownloadPage >= 0 && mDownloadPage < mPageStateArray.length)) { + startWorkers = true; + } + } + + if (startWorkers) { + ensureWorkers(); + } + } + + public void cancelRequest(int index) { + if (mQueenThread == null) { + return; + } + + synchronized (mRequestPageQueue) { + mRequestPageQueue.remove(index); + } + } + /** * @return * String for error
@@ -410,62 +447,72 @@ public class SpiderQueen implements Runnable { } // Get page state - int state = STATE_NONE; - synchronized (mPageStateLock) { - if (mPageStateArray != null && index >= 0 && index < mPageStateArray.length) { - state = mPageStateArray[index]; - } - } + int state = getPageState(index); // Fix state for force if (force && (state == STATE_FINISHED || state == STATE_FAILED)) { state = STATE_NONE; } + // Add to request + synchronized (mRequestPageQueue) { + if (state == STATE_NONE) { + if (force) { + mForceRequestPageQueue.add(index); + } else { + mRequestPageQueue.add(index); + } + } + + // For not force add, add next some pages to request queue + if (!force) { + mRequestPageQueue2.clear(); + int[] pageStateArray = mPageStateArray; + int size; + if (pageStateArray != null) { + size = pageStateArray.length; + } else { + size = Integer.MAX_VALUE; + } + for (int i = index + 1, n = index + i + NUMBER_PRELOAD; i < n && i < size; i++) { + if (STATE_NONE == getPageState(i)) { + mRequestPageQueue2.add(i); + } + } + } + } + + Object result; + switch (state) { default: case STATE_NONE: - // Add to request queue - synchronized (mRequestPageQueue) { - if (force) { - mForceRequestPageQueue.add(index); - } else { - mRequestPageQueue.add(index); - mRequestPageQueue2.clear(); - int[] pageStateArray = mPageStateArray; - int size; - if (pageStateArray != null) { - size = pageStateArray.length; - } else { - size = Integer.MAX_VALUE; - } - for (int i = index + 1, n = index + i + NUMBER_PRELOAD; i < n && i < size; i++) { - mRequestPageQueue2.add(i); - } - } - } - // Only ensure workers when get pages - if (mPageStateArray != null) { - ensureWorkers(); - } - return null; + result = null; + break; case STATE_DOWNLOADING: - return mPagePercentMap.get(index); + result = mPagePercentMap.get(index); + break; case STATE_FAILED: String error = mPageErrorMap.get(index); if (error == null) { error = GetText.getString(R.string.error_unknown); } - return error; + result = error; + break; case STATE_FINISHED: synchronized (mDecodeRequestStack) { - if (!mDecodeRequestStack.contains(index) && index != mDecodeIndex.get()) { + if (!mDecodeRequestStack.contains(index) && index != mDecodingIndex.get()) { mDecodeRequestStack.add(index); mDecodeRequestStack.notify(); } } - return null; + result = null; + break; } + + tryToEnsureWorkers(); + + return result; } private void ensureWorkers() { @@ -652,16 +699,7 @@ public class SpiderQueen implements Runnable { notifyGetPages(spiderInfo.pages); // Ensure worker - boolean startWorkers = false; - synchronized (mRequestPageQueue) { - if (!mForceRequestPageQueue.isEmpty() || !mRequestPageQueue.isEmpty() || !mRequestPageQueue2.isEmpty() || - mDownloadPage >= 0 && mDownloadPage < mPageStateArray.length) { - startWorkers = true; - } - } - if (startWorkers) { - ensureWorkers(); - } + tryToEnsureWorkers(); // Start spider decoder Thread decoderThread = new PriorityThread(new SpiderDecoder(), "SpiderDecoder-" + sIdGenerator.incrementAndGet(), @@ -1119,19 +1157,19 @@ public class SpiderQueen implements Runnable { continue; } index = mDecodeRequestStack.pop(); - mDecodeIndex.lazySet(index); + mDecodingIndex.lazySet(index); } // Check index valid if (index < 0 || index >= mPageStateArray.length) { - mDecodeIndex.lazySet(GalleryPageView.INVALID_INDEX); + mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX); notifyGetImageFailure(index, GetText.getString(R.string.error_out_of_range)); continue; } InputStreamPipe pipe = mSpiderDen.openInputStreamPipe(index); if (pipe == null) { - mDecodeIndex.lazySet(GalleryPageView.INVALID_INDEX); + mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX); notifyGetImageFailure(index, GetText.getString(R.string.error_not_found)); continue; } @@ -1140,14 +1178,14 @@ public class SpiderQueen implements Runnable { pipe.obtain(); Image image = Image.decode(pipe.open(), false); if (image != null) { - mDecodeIndex.lazySet(GalleryPageView.INVALID_INDEX); + mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX); notifyGetImageSuccess(index, image); } else { - mDecodeIndex.lazySet(GalleryPageView.INVALID_INDEX); + mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX); notifyGetImageFailure(index, GetText.getString(R.string.error_decoding_failed)); } } catch (IOException e) { - mDecodeIndex.lazySet(GalleryPageView.INVALID_INDEX); + mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX); notifyGetImageFailure(index, GetText.getString(R.string.error_reading_failed)); } finally { pipe.close(); diff --git a/app/src/main/java/com/hippo/ehviewer/ui/GalleryActivity.java b/app/src/main/java/com/hippo/ehviewer/ui/GalleryActivity.java index 8a85fcad8..af8ae44ba 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/GalleryActivity.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/GalleryActivity.java @@ -756,7 +756,10 @@ public class GalleryActivity extends AppCompatActivity } @Override - public void onUnbind(GalleryPageView view) { + public void onUnbind(GalleryPageView view, int index) { + if (mGalleryProvider != null) { + mGalleryProvider.cancelRequest(index); + } view.setImage(null); view.setError(null, null); } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java index 154ffc5f1..d8ba28af6 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java @@ -313,9 +313,9 @@ public class GalleryPreviewsScene extends ToolbarScene { private static class GetLargePreviewSetListener extends EhCallback> { - private int mTaskId; - private int mGid; - private int mPage; + private final int mTaskId; + private final int mGid; + private final int mPage; public GetLargePreviewSetListener(Context context, int stageId, String sceneTag, int taskId, int gid, int page) { super(context, stageId, sceneTag);