diff options
author | Paul Gardiner <paul.gardiner@artifex.com> | 2013-09-16 13:04:40 +0100 |
---|---|---|
committer | Paul Gardiner <paul.gardiner@artifex.com> | 2013-09-16 13:17:22 +0100 |
commit | 1d6f957544704aa865e91400ba368d11160653ad (patch) | |
tree | 92b17de520055c593de189fca8ece01f54275e9b /platform/android/src/com | |
parent | f5a16fe3f1bc2f40f76692669a0c16be27d644fb (diff) | |
download | mupdf-1d6f957544704aa865e91400ba368d11160653ad.tar.xz |
Android: remove use of Bitmap holder and avoid memory churn
Now use one-time allocation of page-sized bitmaps
Diffstat (limited to 'platform/android/src/com')
9 files changed, 91 insertions, 120 deletions
diff --git a/platform/android/src/com/artifex/mupdfdemo/BitmapHolder.java b/platform/android/src/com/artifex/mupdfdemo/BitmapHolder.java deleted file mode 100644 index 5816e7bb..00000000 --- a/platform/android/src/com/artifex/mupdfdemo/BitmapHolder.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.artifex.mupdfdemo; - -import android.graphics.Bitmap; - -public class BitmapHolder { - private Bitmap bm; - - public BitmapHolder() { - bm = null; - } - - public synchronized void setBm(Bitmap abm) { - if (bm != null && bm != abm) - bm.recycle(); - bm = abm; - } - - public synchronized void drop() { - bm = null; - } - - public synchronized Bitmap getBm() { - return bm; - } -} diff --git a/platform/android/src/com/artifex/mupdfdemo/FilePicker.java b/platform/android/src/com/artifex/mupdfdemo/FilePicker.java index 65e2e901..d1953531 100644 --- a/platform/android/src/com/artifex/mupdfdemo/FilePicker.java +++ b/platform/android/src/com/artifex/mupdfdemo/FilePicker.java @@ -2,11 +2,11 @@ package com.artifex.mupdfdemo; import android.net.Uri; -interface FilePickerSupport { - void performPickFor(FilePicker picker); -} - public abstract class FilePicker { + public interface FilePickerSupport { + void performPickFor(FilePicker picker); + } + private final FilePickerSupport support; FilePicker(FilePickerSupport _support) { diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFActivity.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFActivity.java index e38a3179..2c74b6f8 100644 --- a/platform/android/src/com/artifex/mupdfdemo/MuPDFActivity.java +++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFActivity.java @@ -3,6 +3,8 @@ package com.artifex.mupdfdemo; import java.io.InputStream; import java.util.concurrent.Executor; +import com.artifex.mupdfdemo.ReaderView.ViewMapper; + import android.app.Activity; import android.app.AlertDialog; import android.content.Context; @@ -38,7 +40,7 @@ class ThreadPerTaskExecutor implements Executor { } } -public class MuPDFActivity extends Activity implements FilePickerSupport +public class MuPDFActivity extends Activity implements FilePicker.FilePickerSupport { /* The core rendering instance */ enum TopBarMode {Main, Search, Annot, Delete, More, Accept}; @@ -670,6 +672,11 @@ public class MuPDFActivity extends Activity implements FilePickerSupport public void onDestroy() { + mDocView.applyToChildren(new ReaderView.ViewMapper() { + void applyToView(View view) { + ((MuPDFView)view).releaseBitmaps(); + } + }); if (core != null) core.onDestroy(); if (mAlertTask != null) { diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java index c22f3fa9..d5915f4d 100644 --- a/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java +++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFCore.java @@ -149,31 +149,19 @@ public class MuPDFCore globals = 0; } - public synchronized Bitmap drawPage(int page, + public synchronized void drawPage(Bitmap bm, int page, int pageW, int pageH, int patchX, int patchY, int patchW, int patchH) { gotoPage(page); - Bitmap bm = Bitmap.createBitmap(patchW, patchH, Config.ARGB_8888); drawPage(bm, pageW, pageH, patchX, patchY, patchW, patchH); - return bm; } - public synchronized Bitmap updatePage(BitmapHolder h, int page, + public synchronized void updatePage(Bitmap bm, int page, int pageW, int pageH, int patchX, int patchY, int patchW, int patchH) { - Bitmap bm = null; - Bitmap old_bm = h.getBm(); - - if (old_bm == null) - return null; - - bm = old_bm.copy(Bitmap.Config.ARGB_8888, false); - old_bm = null; - updatePageInternal(bm, page, pageW, pageH, patchX, patchY, patchW, patchH); - return bm; } public synchronized PassClickResult passClickEvent(int page, float x, float y) { diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFPageAdapter.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFPageAdapter.java index 83d6a3fc..6ed10fe4 100644 --- a/platform/android/src/com/artifex/mupdfdemo/MuPDFPageAdapter.java +++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFPageAdapter.java @@ -1,6 +1,7 @@ package com.artifex.mupdfdemo; import android.content.Context; +import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.PointF; import android.util.SparseArray; @@ -10,11 +11,12 @@ import android.widget.BaseAdapter; public class MuPDFPageAdapter extends BaseAdapter { private final Context mContext; - private final FilePickerSupport mFilePickerSupport; + private final FilePicker.FilePickerSupport mFilePickerSupport; private final MuPDFCore mCore; private final SparseArray<PointF> mPageSizes = new SparseArray<PointF>(); + private Bitmap mSharedHqBm; - public MuPDFPageAdapter(Context c, FilePickerSupport filePickerSupport, MuPDFCore core) { + public MuPDFPageAdapter(Context c, FilePicker.FilePickerSupport filePickerSupport, MuPDFCore core) { mContext = c; mFilePickerSupport = filePickerSupport; mCore = core; @@ -35,7 +37,10 @@ public class MuPDFPageAdapter extends BaseAdapter { public View getView(final int position, View convertView, ViewGroup parent) { final MuPDFPageView pageView; if (convertView == null) { - pageView = new MuPDFPageView(mContext, mFilePickerSupport, mCore, new Point(parent.getWidth(), parent.getHeight())); + if (mSharedHqBm == null || mSharedHqBm.getWidth() != parent.getWidth() || mSharedHqBm.getWidth() != parent.getWidth()) + mSharedHqBm = Bitmap.createBitmap(parent.getWidth(), parent.getHeight(), Bitmap.Config.ARGB_8888); + + pageView = new MuPDFPageView(mContext, mFilePickerSupport, mCore, new Point(parent.getWidth(), parent.getHeight()), mSharedHqBm); } else { pageView = (MuPDFPageView) convertView; } diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFPageView.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFPageView.java index 774aafb7..2b8949eb 100644 --- a/platform/android/src/com/artifex/mupdfdemo/MuPDFPageView.java +++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFPageView.java @@ -83,7 +83,7 @@ class PassClickResultSignature extends PassClickResult { } public class MuPDFPageView extends PageView implements MuPDFView { - final private FilePickerSupport mFilePickerSupport; + final private FilePicker.FilePickerSupport mFilePickerSupport; private final MuPDFCore mCore; private AsyncTask<Void,Void,PassClickResult> mPassClick; private RectF mWidgetAreas[]; @@ -109,8 +109,8 @@ public class MuPDFPageView extends PageView implements MuPDFView { private AsyncTask<Void,Void,Boolean> mSign; private Runnable changeReporter; - public MuPDFPageView(Context c, FilePickerSupport filePickerSupport, MuPDFCore core, Point parentSize) { - super(c, parentSize); + public MuPDFPageView(Context c, FilePicker.FilePickerSupport filePickerSupport, MuPDFCore core, Point parentSize, Bitmap sharedHqBm) { + super(c, parentSize, sharedHqBm); mFilePickerSupport = filePickerSupport; mCore = core; mTextEntryBuilder = new AlertDialog.Builder(c); @@ -549,15 +549,15 @@ public class MuPDFPageView extends PageView implements MuPDFView { } @Override - protected Bitmap drawPage(int sizeX, int sizeY, + protected void drawPage(Bitmap bm, int sizeX, int sizeY, int patchX, int patchY, int patchWidth, int patchHeight) { - return mCore.drawPage(mPageNumber, sizeX, sizeY, patchX, patchY, patchWidth, patchHeight); + mCore.drawPage(bm, mPageNumber, sizeX, sizeY, patchX, patchY, patchWidth, patchHeight); } @Override - protected Bitmap updatePage(BitmapHolder h, int sizeX, int sizeY, + protected void updatePage(Bitmap bm, int sizeX, int sizeY, int patchX, int patchY, int patchWidth, int patchHeight) { - return mCore.updatePage(h, mPageNumber, sizeX, sizeY, patchX, patchY, patchWidth, patchHeight); + mCore.updatePage(bm, mPageNumber, sizeX, sizeY, patchX, patchY, patchWidth, patchHeight); } @Override diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java index 0c7074bc..eb655656 100644 --- a/platform/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java +++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFReflowView.java @@ -147,6 +147,9 @@ public class MuPDFReflowView extends WebView implements MuPDFView { } } + public void releaseBitmaps() { + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int x, y; diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFView.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFView.java index cc0405d1..f57f7eb8 100644 --- a/platform/android/src/com/artifex/mupdfdemo/MuPDFView.java +++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFView.java @@ -29,4 +29,5 @@ public interface MuPDFView { public void addHq(boolean update); public void removeHq(); public void releaseResources(); + public void releaseBitmaps(); } diff --git a/platform/android/src/com/artifex/mupdfdemo/PageView.java b/platform/android/src/com/artifex/mupdfdemo/PageView.java index 200821dd..cc00e004 100644 --- a/platform/android/src/com/artifex/mupdfdemo/PageView.java +++ b/platform/android/src/com/artifex/mupdfdemo/PageView.java @@ -5,8 +5,10 @@ import java.util.Iterator; import android.content.Context; import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Point; @@ -20,15 +22,11 @@ import android.widget.ImageView; import android.widget.ProgressBar; class PatchInfo { - public BitmapHolder bmh; - public Bitmap bm; public Point patchViewSize; public Rect patchArea; public boolean completeRedraw; - public PatchInfo(Point aPatchViewSize, Rect aPatchArea, BitmapHolder aBmh, boolean aCompleteRedraw) { - bmh = aBmh; - bm = null; + public PatchInfo(Point aPatchViewSize, Rect aPatchArea, boolean aCompleteRedraw) { patchViewSize = aPatchViewSize; patchArea = aPatchArea; completeRedraw = aCompleteRedraw; @@ -115,15 +113,16 @@ public abstract class PageView extends ViewGroup { protected float mSourceScale; private ImageView mEntire; // Image rendered at minimum zoom - private BitmapHolder mEntireBmh; + private Bitmap mEntireBm; + private Matrix mEntireMat; private AsyncTask<Void,Void,TextWord[][]> mGetText; private AsyncTask<Void,Void,LinkInfo[]> mGetLinkInfo; - private AsyncTask<Void,Void,Bitmap> mDrawEntire; + private AsyncTask<Void,Void,Void> mDrawEntire; private Point mPatchViewSize; // View size on the basis of which the patch was created private Rect mPatchArea; private ImageView mPatch; - private BitmapHolder mPatchBmh; + private Bitmap mPatchBm; private AsyncTask<PatchInfo,Void,PatchInfo> mDrawPatch; private RectF mSearchBoxes[]; protected LinkInfo mLinks[]; @@ -138,17 +137,18 @@ public abstract class PageView extends ViewGroup { private ProgressBar mBusyIndicator; private final Handler mHandler = new Handler(); - public PageView(Context c, Point parentSize) { + public PageView(Context c, Point parentSize, Bitmap sharedHqBm) { super(c); mContext = c; mParentSize = parentSize; setBackgroundColor(BACKGROUND_COLOR); - mEntireBmh = new BitmapHolder(); - mPatchBmh = new BitmapHolder(); + mEntireBm = Bitmap.createBitmap(parentSize.x, parentSize.y, Config.ARGB_8888); + mPatchBm = sharedHqBm; + mEntireMat = new Matrix(); } - protected abstract Bitmap drawPage(int sizeX, int sizeY, int patchX, int patchY, int patchWidth, int patchHeight); - protected abstract Bitmap updatePage(BitmapHolder h, int sizeX, int sizeY, int patchX, int patchY, int patchWidth, int patchHeight); + 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 LinkInfo[] getLinkInfo(); protected abstract TextWord[][] getText(); protected abstract void addMarkup(PointF[] quadPoints, Annotation.Type type); @@ -183,12 +183,12 @@ public abstract class PageView extends ViewGroup { if (mEntire != null) { mEntire.setImageBitmap(null); - mEntireBmh.setBm(null); + mEntire.invalidate(); } if (mPatch != null) { mPatch.setImageBitmap(null); - mPatchBmh.setBm(null); + mPatch.invalidate(); } mPatchViewSize = null; @@ -210,6 +210,12 @@ public abstract class PageView extends ViewGroup { } } + public void releaseBitmaps() { + reinit(); + mEntireBm = null; + mPatchBm = null; + } + public void blank(int page) { reinit(); mPageNumber = page; @@ -239,7 +245,7 @@ public abstract class PageView extends ViewGroup { mPageNumber = page; if (mEntire == null) { mEntire = new OpaqueImageView(mContext); - mEntire.setScaleType(ImageView.ScaleType.FIT_CENTER); + mEntire.setScaleType(ImageView.ScaleType.MATRIX); addView(mEntire); } @@ -250,7 +256,7 @@ public abstract class PageView extends ViewGroup { mSize = newSize; mEntire.setImageBitmap(null); - mEntireBmh.setBm(null); + mEntire.invalidate(); // Get the link info in the background mGetLinkInfo = new AsyncTask<Void,Void,LinkInfo[]>() { @@ -260,22 +266,24 @@ public abstract class PageView extends ViewGroup { protected void onPostExecute(LinkInfo[] v) { mLinks = v; - invalidate(); + if (mSearchView != null) + mSearchView.invalidate(); } }; mGetLinkInfo.execute(); // Render the page in the background - mDrawEntire = new AsyncTask<Void,Void,Bitmap>() { - protected Bitmap doInBackground(Void... v) { - return drawPage(mSize.x, mSize.y, 0, 0, mSize.x, mSize.y); + 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; } protected void onPreExecute() { setBackgroundColor(BACKGROUND_COLOR); mEntire.setImageBitmap(null); - mEntireBmh.setBm(null); + mEntire.invalidate(); if (mBusyIndicator == null) { mBusyIndicator = new ProgressBar(mContext); @@ -292,11 +300,11 @@ public abstract class PageView extends ViewGroup { } } - protected void onPostExecute(Bitmap bm) { + protected void onPostExecute(Void v) { removeView(mBusyIndicator); mBusyIndicator = null; - mEntire.setImageBitmap(bm); - mEntireBmh.setBm(bm); + mEntire.setImageBitmap(mEntireBm); + mEntire.invalidate(); setBackgroundColor(Color.TRANSPARENT); } }; @@ -531,6 +539,9 @@ public abstract class PageView extends ViewGroup { int h = bottom-top; if (mEntire != null) { + mEntireMat.setScale(w/(float)mSize.x, h/(float)mSize.y); + mEntire.setImageMatrix(mEntireMat); + mEntire.invalidate(); mEntire.layout(0, 0, w, h); } @@ -545,7 +556,7 @@ public abstract class PageView extends ViewGroup { mPatchArea = null; if (mPatch != null) { mPatch.setImageBitmap(null); - mPatchBmh.setBm(null); + mPatch.invalidate(); } } else { mPatch.layout(mPatchArea.left, mPatchArea.top, mPatchArea.right, mPatchArea.bottom); @@ -588,19 +599,10 @@ public abstract class PageView extends ViewGroup { mDrawPatch = null; } - if (completeRedraw) { - // The bitmap holder mPatchBm may still be rendered to by a - // previously invoked task, and possibly for a different - // area, so we cannot risk the bitmap generated by this task - // being passed to it - mPatchBmh.drop(); - mPatchBmh = new BitmapHolder(); - } - // Create and add the image view if not already done if (mPatch == null) { mPatch = new OpaqueImageView(mContext); - mPatch.setScaleType(ImageView.ScaleType.FIT_CENTER); + mPatch.setScaleType(ImageView.ScaleType.MATRIX); addView(mPatch); mSearchView.bringToFront(); } @@ -608,11 +610,11 @@ public abstract class PageView extends ViewGroup { mDrawPatch = new AsyncTask<PatchInfo,Void,PatchInfo>() { protected PatchInfo doInBackground(PatchInfo... v) { if (v[0].completeRedraw) { - v[0].bm = drawPage(v[0].patchViewSize.x, v[0].patchViewSize.y, + 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 { - v[0].bm = updatePage(v[0].bmh, v[0].patchViewSize.x, v[0].patchViewSize.y, + 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()); } @@ -621,24 +623,19 @@ public abstract class PageView extends ViewGroup { } protected void onPostExecute(PatchInfo v) { - if (mPatchBmh == v.bmh) { - mPatchViewSize = v.patchViewSize; - mPatchArea = v.patchArea; - if (v.bm != null) { - mPatch.setImageBitmap(v.bm); - v.bmh.setBm(v.bm); - v.bm = null; - } - //requestLayout(); - // Calling requestLayout here doesn't lead to a later call to layout. No idea - // why, but apparently others have run into the problem. - mPatch.layout(mPatchArea.left, mPatchArea.top, mPatchArea.right, mPatchArea.bottom); - invalidate(); - } + mPatchViewSize = v.patchViewSize; + mPatchArea = v.patchArea; + mPatch.setImageBitmap(mPatchBm); + mPatch.invalidate(); + //requestLayout(); + // Calling requestLayout here doesn't lead to a later call to layout. No idea + // why, but apparently others have run into the problem. + mPatch.layout(mPatchArea.left, mPatchArea.top, mPatchArea.right, mPatchArea.bottom); + invalidate(); } }; - mDrawPatch.execute(new PatchInfo(patchViewSize, patchArea, mPatchBmh, completeRedraw)); + mDrawPatch.execute(new PatchInfo(patchViewSize, patchArea, completeRedraw)); } } @@ -655,20 +652,15 @@ public abstract class PageView extends ViewGroup { } // Render the page in the background - mDrawEntire = new AsyncTask<Void,Void,Bitmap>() { - protected Bitmap doInBackground(Void... v) { - // Pass the current bitmap as a basis for the update, but use a bitmap - // holder so that the held bitmap will be nulled and not hold on to - // memory, should this view become redundant. - return updatePage(mEntireBmh, mSize.x, mSize.y, 0, 0, mSize.x, mSize.y); + 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; } - protected void onPostExecute(Bitmap bm) { - if (bm != null) { - mEntire.setImageBitmap(bm); - mEntireBmh.setBm(bm); - } - invalidate(); + protected void onPostExecute(Void v) { + mEntire.setImageBitmap(mEntireBm); + mEntire.invalidate(); } }; @@ -689,7 +681,7 @@ public abstract class PageView extends ViewGroup { mPatchArea = null; if (mPatch != null) { mPatch.setImageBitmap(null); - mPatchBmh.setBm(null); + mPatch.invalidate(); } } |