Add GalleryProvider.cancelRequest(int), fix SpiderQueen.request(int, boolean)

This commit is contained in:
seven332 committed 2016-02-28 15:39:21 +08:00
1 parent efdb488781
commit feb9bbadc6
9 files changed
+144 -61

No files matched your search

@@ -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";
@@ -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<Integer> 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");
@@ -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) {
@@ -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) {
@@ -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<Integer> 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));
}
}
@@ -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
@@ -130,7 +130,7 @@ public class SpiderQueen implements Runnable {
@Nullable
private Thread mDecoderThread;
private final Stack<Integer> 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<br>
@@ -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();
@@ -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);
}
@@ -313,9 +313,9 @@ public class GalleryPreviewsScene extends ToolbarScene {
private static class GetLargePreviewSetListener extends EhCallback<GalleryPreviewsScene, Pair<LargePreviewSet, Integer>> {
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);