From fb7206c262a5f9ff0e39e89946846771479ba3ec Mon Sep 17 00:00:00 2001 From: fredrossperry Date: Thu, 30 Jul 2015 08:58:39 -0700 Subject: Android: Changes to improve handling out-of-memory errors. Probably related to bug 695507. --- .../src/com/artifex/mupdfdemo/MuPDFActivity.java | 12 +++++- .../com/artifex/mupdfdemo/MuPDFPageAdapter.java | 8 ++++ .../src/com/artifex/mupdfdemo/PageView.java | 8 ++++ .../src/com/artifex/mupdfdemo/ReaderView.java | 48 +++++++++++++++++++++- 4 files changed, 73 insertions(+), 3 deletions(-) (limited to 'platform/android') diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFActivity.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFActivity.java index 30e96ecf..7b4a6040 100644 --- a/platform/android/src/com/artifex/mupdfdemo/MuPDFActivity.java +++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFActivity.java @@ -87,6 +87,9 @@ public class MuPDFActivity extends Activity implements FilePicker.FilePickerSupp private FilePicker mFilePicker; private String mProofFile; + static private AlertDialog.Builder gAlertBuilder; + static public AlertDialog.Builder getAlertBuilder() {return gAlertBuilder;} + public void createAlertWaiter() { mAlertsActive = true; // All mupdf library calls are performed on asynchronous tasks to avoid stalling @@ -223,6 +226,12 @@ public class MuPDFActivity extends Activity implements FilePicker.FilePickerSupp System.out.println(e); return null; } + catch (java.lang.OutOfMemoryError e) + { + // out of memory is not an Exception, so we catch it separately. + System.out.println(e); + return null; + } return core; } @@ -245,11 +254,12 @@ public class MuPDFActivity extends Activity implements FilePicker.FilePickerSupp /** Called when the activity is first created. */ @Override - public void onCreate(Bundle savedInstanceState) + public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); mAlertBuilder = new AlertDialog.Builder(this); + gAlertBuilder = mAlertBuilder; // keep a static copy of this that other classes can use if (core == null) { core = (MuPDFCore)getLastNonConfigurationInstance(); diff --git a/platform/android/src/com/artifex/mupdfdemo/MuPDFPageAdapter.java b/platform/android/src/com/artifex/mupdfdemo/MuPDFPageAdapter.java index 36c17a97..abdac845 100644 --- a/platform/android/src/com/artifex/mupdfdemo/MuPDFPageAdapter.java +++ b/platform/android/src/com/artifex/mupdfdemo/MuPDFPageAdapter.java @@ -34,6 +34,14 @@ public class MuPDFPageAdapter extends BaseAdapter { return 0; } + public void releaseBitmaps() + { + // recycle and release the shared bitmap. + if (mSharedHqBm!=null) + mSharedHqBm.recycle(); + mSharedHqBm = null; + } + public View getView(final int position, View convertView, ViewGroup parent) { final MuPDFPageView pageView; if (convertView == null) { diff --git a/platform/android/src/com/artifex/mupdfdemo/PageView.java b/platform/android/src/com/artifex/mupdfdemo/PageView.java index c7fecea1..2ee407cb 100644 --- a/platform/android/src/com/artifex/mupdfdemo/PageView.java +++ b/platform/android/src/com/artifex/mupdfdemo/PageView.java @@ -200,7 +200,15 @@ public abstract class PageView extends ViewGroup { public void releaseBitmaps() { reinit(); + + // recycle bitmaps before releasing them. + + if (mEntireBm!=null) + mEntireBm.recycle(); mEntireBm = null; + + if (mPatchBm!=null) + mPatchBm.recycle(); mPatchBm = null; } diff --git a/platform/android/src/com/artifex/mupdfdemo/ReaderView.java b/platform/android/src/com/artifex/mupdfdemo/ReaderView.java index 7b129916..65d8f665 100644 --- a/platform/android/src/com/artifex/mupdfdemo/ReaderView.java +++ b/platform/android/src/com/artifex/mupdfdemo/ReaderView.java @@ -3,6 +3,11 @@ package com.artifex.mupdfdemo; import java.util.LinkedList; import java.util.NoSuchElementException; +import android.app.Activity; +import android.app.ActivityManager; +import android.app.AlertDialog; +import android.content.DialogInterface; + import android.content.Context; import android.graphics.Point; import android.graphics.Rect; @@ -552,6 +557,7 @@ public class ReaderView } } + requestLayout(); return true; } @@ -565,10 +571,40 @@ public class ReaderView } @Override - protected void onLayout(boolean changed, int left, int top, int right, - int bottom) { + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); + try { + onLayout2(changed, left, top, right, bottom); + } + catch (java.lang.OutOfMemoryError e) { + System.out.println("Out of memory during layout"); + + // we might get an out of memory error. + // so let's display an alert. + // TODO: a better message, in resources. + + if (!memAlert) { + memAlert = true; + AlertDialog alertDialog = MuPDFActivity.getAlertBuilder().create(); + alertDialog.setMessage("Out of memory during layout"); + alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK", + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + memAlert = false; + } + }); + alertDialog.show(); + } + } + } + + private boolean memAlert = false; + + private void onLayout2(boolean changed, int left, int top, int right, + int bottom) { + // "Edit mode" means when the View is being displayed in the Android GUI editor. (this class // is instantiated in the IDE, so we need to be a bit careful what we do). if (isInEditMode()) @@ -752,6 +788,14 @@ public class ReaderView @Override public void setAdapter(Adapter adapter) { + + // release previous adapter's bitmaps + if (null!=mAdapter && adapter!=mAdapter) { + if (adapter instanceof MuPDFPageAdapter){ + ((MuPDFPageAdapter) adapter).releaseBitmaps(); + } + } + mAdapter = adapter; requestLayout(); -- cgit v1.2.3