diff options
Diffstat (limited to 'platform/android/src/com')
6 files changed, 223 insertions, 68 deletions
diff --git a/platform/android/src/com/artifex/mupdfdemo/CancellableAsyncTask.java b/platform/android/src/com/artifex/mupdfdemo/CancellableAsyncTask.java new file mode 100644 index 00000000..fcb1b744 --- /dev/null +++ b/platform/android/src/com/artifex/mupdfdemo/CancellableAsyncTask.java @@ -0,0 +1,79 @@ +package com.artifex.mupdfdemo; + +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; + +// Ideally this would be a subclass of AsyncTask, however the cancel() method is final, and cannot +// be overridden. I felt that having two different, but similar cancel methods was a bad idea. +public class CancellableAsyncTask<Params, Result> +{ + private final AsyncTask<Params, Void, Result> asyncTask; + private final CancellableTaskDefinition<Params, Result> ourTask; + + public void onPreExecute() + { + + } + + public void onPostExecute(Result result) + { + + } + + public CancellableAsyncTask(final CancellableTaskDefinition<Params, Result> task) + { + if (task == null) + throw new IllegalArgumentException(); + + this.ourTask = task; + asyncTask = new AsyncTask<Params, Void, Result>() + { + @Override + protected Result doInBackground(Params... params) + { + return task.doInBackground(params); + } + + @Override + protected void onPreExecute() + { + CancellableAsyncTask.this.onPreExecute(); + } + + @Override + protected void onPostExecute(Result result) + { + CancellableAsyncTask.this.onPostExecute(result); + task.doCleanup(); + } + }; + } + + public void cancelAndWait() + { + this.asyncTask.cancel(true); + ourTask.doCancel(); + + try + { + this.asyncTask.get(); + } + catch (InterruptedException e) + { + } + catch (ExecutionException e) + { + } + catch (CancellationException e) + { + } + + ourTask.doCleanup(); + } + + public void execute(Params ... params) + { + asyncTask.execute(params); + } + +} diff --git a/platform/android/src/com/artifex/mupdfdemo/CancellableTaskDefinition.java b/platform/android/src/com/artifex/mupdfdemo/CancellableTaskDefinition.java new file mode 100644 index 00000000..62b04f30 --- /dev/null +++ b/platform/android/src/com/artifex/mupdfdemo/CancellableTaskDefinition.java @@ -0,0 +1,8 @@ +package com.artifex.mupdfdemo; + +public interface CancellableTaskDefinition <Params, Result> +{ + public Result doInBackground(Params ... params); + public void doCancel(); + public void doCleanup(); +} diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFCancellableTaskDefinition.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFCancellableTaskDefinition.java new file mode 100644 index 00000000..b95d8e93 --- /dev/null +++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFCancellableTaskDefinition.java @@ -0,0 +1,38 @@ +package com.artifex.mupdfdemo; + +public abstract class MuPDFCancellableTaskDefinition<Params, Result> implements CancellableTaskDefinition<Params, Result> +{ + private MuPDFCore.Cookie cookie; + + public MuPDFCancellableTaskDefinition(MuPDFCore core) + { + this.cookie = core.new Cookie(); + } + + @Override + public void doCancel() + { + if (cookie == null) + return; + + cookie.abort(); + } + + @Override + public void doCleanup() + { + if (cookie == null) + return; + + cookie.destroy(); + cookie = null; + } + + @Override + public final Result doInBackground(Params ... params) + { + return doInBackground(cookie, params); + } + + public abstract Result doInBackground(MuPDFCore.Cookie cookie, Params ... params); +} diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java index ecdeccc7..ec35ef7c 100644 --- a/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java +++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java @@ -33,12 +33,14 @@ public class MuPDFCore private native void drawPage(Bitmap bitmap, int pageW, int pageH, int patchX, int patchY, - int patchW, int patchH); + int patchW, int patchH, + long cookiePtr); private native void updatePageInternal(Bitmap bitmap, int page, int pageW, int pageH, int patchX, int patchY, - int patchW, int patchH); + int patchW, int patchH, + long cookiePtr); private native RectF[] searchPage(String text); private native TextChar[][][][] text(); private native byte[] textAsHtml(); @@ -69,9 +71,36 @@ public class MuPDFCore private native void destroying(); private native boolean hasChangesInternal(); private native void saveInternal(); + private native long createCookie(); + private native void destroyCookie(long cookie); + private native void abortCookie(long cookie); public native boolean javascriptSupported(); + public class Cookie + { + private final long cookiePtr; + + public Cookie() + { + cookiePtr = createCookie(); + if (cookiePtr == 0) + throw new OutOfMemoryError(); + } + + public void abort() + { + abortCookie(cookiePtr); + } + + public void destroy() + { + // We could do this in finalize, but there's no guarantee that + // a finalize will occur before the muPDF context occurs. + destroyCookie(cookiePtr); + } + } + public MuPDFCore(Context context, String filename) throws Exception { globals = openFile(filename); @@ -152,16 +181,18 @@ public class MuPDFCore public synchronized void drawPage(Bitmap bm, int page, int pageW, int pageH, int patchX, int patchY, - int patchW, int patchH) { + int patchW, int patchH, + MuPDFCore.Cookie cookie) { gotoPage(page); - drawPage(bm, pageW, pageH, patchX, patchY, patchW, patchH); + drawPage(bm, pageW, pageH, patchX, patchY, patchW, patchH, cookie.cookiePtr); } public synchronized void updatePage(Bitmap bm, int page, int pageW, int pageH, int patchX, int patchY, - int patchW, int patchH) { - updatePageInternal(bm, page, pageW, pageH, patchX, patchY, patchW, patchH); + int patchW, int patchH, + MuPDFCore.Cookie cookie) { + updatePageInternal(bm, page, pageW, pageH, patchX, patchY, patchW, patchH, cookie.cookiePtr); } public synchronized PassClickResult passClickEvent(int page, float x, float y) { diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFPageView.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFPageView.java index 0d3cc961..c18f44ab 100644 --- a/platform/android/src/com/artifex/mupdfdemo/MuPDFPageView.java +++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFPageView.java @@ -2,6 +2,8 @@ package com.artifex.mupdfdemo; import java.util.ArrayList; +import com.artifex.mupdfdemo.MuPDFCore.Cookie; + import android.annotation.TargetApi; import android.app.AlertDialog; import android.content.ClipData; @@ -550,16 +552,31 @@ public class MuPDFPageView extends PageView implements MuPDFView { return true; } + @Override - protected void drawPage(Bitmap bm, int sizeX, int sizeY, - int patchX, int patchY, int patchWidth, int patchHeight) { - mCore.drawPage(bm, mPageNumber, sizeX, sizeY, patchX, patchY, patchWidth, patchHeight); + protected CancellableTaskDefinition<Void, Void> getDrawPageTask(final Bitmap bm, final int sizeX, final int sizeY, + final int patchX, final int patchY, final int patchWidth, final int patchHeight) { + return new MuPDFCancellableTaskDefinition<Void, Void>(mCore) { + @Override + public Void doInBackground(MuPDFCore.Cookie cookie, Void ... params) { + mCore.drawPage(bm, mPageNumber, sizeX, sizeY, patchX, patchY, patchWidth, patchHeight, cookie); + return null; + } + }; + } - @Override - protected void updatePage(Bitmap bm, int sizeX, int sizeY, - int patchX, int patchY, int patchWidth, int patchHeight) { - mCore.updatePage(bm, mPageNumber, sizeX, sizeY, patchX, patchY, patchWidth, patchHeight); + protected CancellableTaskDefinition<Void, Void> getUpdatePageTask(final Bitmap bm, final int sizeX, final int sizeY, + final int patchX, final int patchY, final int patchWidth, final int patchHeight) + { + return new MuPDFCancellableTaskDefinition<Void, Void>(mCore) { + + @Override + public Void doInBackground(MuPDFCore.Cookie cookie, Void ... params) { + mCore.updatePage(bm, mPageNumber, sizeX, sizeY, patchX, patchY, patchWidth, patchHeight, cookie); + return null; + } + }; } @Override diff --git a/platform/android/src/com/artifex/mupdfdemo/PageView.java b/platform/android/src/com/artifex/mupdfdemo/PageView.java index b7ef580d..c7fecea1 100644 --- a/platform/android/src/com/artifex/mupdfdemo/PageView.java +++ b/platform/android/src/com/artifex/mupdfdemo/PageView.java @@ -21,18 +21,6 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.ProgressBar; -class PatchInfo { - public Point patchViewSize; - public Rect patchArea; - public boolean completeRedraw; - - public PatchInfo(Point aPatchViewSize, Rect aPatchArea, boolean aCompleteRedraw) { - patchViewSize = aPatchViewSize; - patchArea = aPatchArea; - completeRedraw = aCompleteRedraw; - } -} - // Make our ImageViews opaque to optimize redraw class OpaqueImageView extends ImageView { @@ -117,13 +105,13 @@ public abstract class PageView extends ViewGroup { private Matrix mEntireMat; private AsyncTask<Void,Void,TextWord[][]> mGetText; private AsyncTask<Void,Void,LinkInfo[]> mGetLinkInfo; - private AsyncTask<Void,Void,Void> mDrawEntire; + private CancellableAsyncTask<Void, Void> mDrawEntire; private Point mPatchViewSize; // View size on the basis of which the patch was created private Rect mPatchArea; private ImageView mPatch; private Bitmap mPatchBm; - private AsyncTask<PatchInfo,Void,PatchInfo> mDrawPatch; + private CancellableAsyncTask<Void,Void> mDrawPatch; private RectF mSearchBoxes[]; protected LinkInfo mLinks[]; private RectF mSelectBox; @@ -147,8 +135,8 @@ public abstract class PageView extends ViewGroup { mEntireMat = new Matrix(); } - protected abstract void drawPage(Bitmap bm, int sizeX, int sizeY, int patchX, int patchY, int patchWidth, int patchHeight); - protected abstract void updatePage(Bitmap bm, int sizeX, int sizeY, int patchX, int patchY, int patchWidth, int patchHeight); + protected abstract CancellableTaskDefinition<Void, Void> getDrawPageTask(Bitmap bm, int sizeX, int sizeY, int patchX, int patchY, int patchWidth, int patchHeight); + protected abstract CancellableTaskDefinition<Void, Void> getUpdatePageTask(Bitmap bm, int sizeX, int sizeY, int patchX, int patchY, int patchWidth, int patchHeight); protected abstract LinkInfo[] getLinkInfo(); protected abstract TextWord[][] getText(); protected abstract void addMarkup(PointF[] quadPoints, Annotation.Type type); @@ -156,12 +144,12 @@ public abstract class PageView extends ViewGroup { private void reinit() { // Cancel pending render task if (mDrawEntire != null) { - mDrawEntire.cancel(true); + mDrawEntire.cancelAndWait(); mDrawEntire = null; } if (mDrawPatch != null) { - mDrawPatch.cancel(true); + mDrawPatch.cancelAndWait(); mDrawPatch = null; } @@ -233,7 +221,7 @@ public abstract class PageView extends ViewGroup { public void setPage(int page, PointF size) { // Cancel pending render task if (mDrawEntire != null) { - mDrawEntire.cancel(true); + mDrawEntire.cancelAndWait(); mDrawEntire = null; } @@ -274,13 +262,10 @@ public abstract class PageView extends ViewGroup { mGetLinkInfo.execute(); // Render the page in the background - mDrawEntire = new AsyncTask<Void,Void,Void>() { - protected Void doInBackground(Void... v) { - drawPage(mEntireBm, mSize.x, mSize.y, 0, 0, mSize.x, mSize.y); - return null; - } + mDrawEntire = new CancellableAsyncTask<Void, Void>(getDrawPageTask(mEntireBm, mSize.x, mSize.y, 0, 0, mSize.x, mSize.y)) { - protected void onPreExecute() { + @Override + public void onPreExecute() { setBackgroundColor(BACKGROUND_COLOR); mEntire.setImageBitmap(null); mEntire.invalidate(); @@ -300,12 +285,14 @@ public abstract class PageView extends ViewGroup { } } - protected void onPostExecute(Void v) { + @Override + public void onPostExecute(Void result) { removeView(mBusyIndicator); mBusyIndicator = null; mEntire.setImageBitmap(mEntireBm); mEntire.invalidate(); setBackgroundColor(Color.TRANSPARENT); + } }; @@ -588,8 +575,8 @@ public abstract class PageView extends ViewGroup { mPatch.invalidate(); } } else { - Point patchViewSize = new Point(viewArea.width(), viewArea.height()); - Rect patchArea = new Rect(0, 0, mParentSize.x, mParentSize.y); + final Point patchViewSize = new Point(viewArea.width(), viewArea.height()); + final Rect patchArea = new Rect(0, 0, mParentSize.x, mParentSize.y); // Intersect and test that there is an intersection if (!patchArea.intersect(viewArea)) @@ -608,7 +595,7 @@ public abstract class PageView extends ViewGroup { // Stop the drawing of previous patch if still going if (mDrawPatch != null) { - mDrawPatch.cancel(true); + mDrawPatch.cancelAndWait(); mDrawPatch = null; } @@ -620,24 +607,22 @@ public abstract class PageView extends ViewGroup { mSearchView.bringToFront(); } - mDrawPatch = new AsyncTask<PatchInfo,Void,PatchInfo>() { - protected PatchInfo doInBackground(PatchInfo... v) { - if (v[0].completeRedraw) { - drawPage(mPatchBm, v[0].patchViewSize.x, v[0].patchViewSize.y, - v[0].patchArea.left, v[0].patchArea.top, - v[0].patchArea.width(), v[0].patchArea.height()); - } else { - updatePage(mPatchBm, v[0].patchViewSize.x, v[0].patchViewSize.y, - v[0].patchArea.left, v[0].patchArea.top, - v[0].patchArea.width(), v[0].patchArea.height()); - } + CancellableTaskDefinition<Void, Void> task; - return v[0]; - } + if (completeRedraw) + task = getDrawPageTask(mPatchBm, patchViewSize.x, patchViewSize.y, + patchArea.left, patchArea.top, + patchArea.width(), patchArea.height()); + else + task = getUpdatePageTask(mPatchBm, patchViewSize.x, patchViewSize.y, + patchArea.left, patchArea.top, + patchArea.width(), patchArea.height()); + + mDrawPatch = new CancellableAsyncTask<Void,Void>(task) { - protected void onPostExecute(PatchInfo v) { - mPatchViewSize = v.patchViewSize; - mPatchArea = v.patchArea; + public void onPostExecute(Void result) { + mPatchViewSize = patchViewSize; + mPatchArea = patchArea; mPatch.setImageBitmap(mPatchBm); mPatch.invalidate(); //requestLayout(); @@ -647,30 +632,27 @@ public abstract class PageView extends ViewGroup { } }; - mDrawPatch.execute(new PatchInfo(patchViewSize, patchArea, completeRedraw)); + mDrawPatch.execute(); } } public void update() { // Cancel pending render task if (mDrawEntire != null) { - mDrawEntire.cancel(true); + mDrawEntire.cancelAndWait(); mDrawEntire = null; } if (mDrawPatch != null) { - mDrawPatch.cancel(true); + mDrawPatch.cancelAndWait(); mDrawPatch = null; } + // Render the page in the background - mDrawEntire = new AsyncTask<Void,Void,Void>() { - protected Void doInBackground(Void... v) { - updatePage(mEntireBm, mSize.x, mSize.y, 0, 0, mSize.x, mSize.y); - return null; - } + mDrawEntire = new CancellableAsyncTask<Void, Void>(getUpdatePageTask(mEntireBm, mSize.x, mSize.y, 0, 0, mSize.x, mSize.y)) { - protected void onPostExecute(Void v) { + public void onPostExecute(Void result) { mEntire.setImageBitmap(mEntireBm); mEntire.invalidate(); } @@ -684,7 +666,7 @@ public abstract class PageView extends ViewGroup { public void removeHq() { // Stop the drawing of the patch if still going if (mDrawPatch != null) { - mDrawPatch.cancel(true); + mDrawPatch.cancelAndWait(); mDrawPatch = null; } |