2017-12-29 28 views
1

私のアプリケーションでは、PDFファイルをビットマップでレンダリングしたいと考えています。私はStackOverflowで多くのソリューションを見つけましたが、これまでのところ何もできませんでした。私はここでスタックトレースOutOfMemoryError例外をスローする

FATAL EXCEPTION: main 
Process: com.myclasscampus.aspire, PID: 6214 
java.lang.OutOfMemoryError: Failed to allocate a 434035012 byte allocation with 4194304 free bytes and 328MB until OOM 
at dalvik.system.VMRuntime.newNonMovableArray(Native Method) 
at android.graphics.Bitmap.nativeCreate(Native Method) 
at android.graphics.Bitmap.createBitmap(Bitmap.java:879) 
at android.graphics.Bitmap.createBitmap(Bitmap.java:856) 
at android.graphics.Bitmap.createBitmap(Bitmap.java:823) 
at com.aspire.pdfViewer.PDFViewFragment.showPage(PDFViewFragment.java:176) 
at com.aspire.pdfViewer.PDFViewFragment.openRenderer(PDFViewFragment.java:154) 
at com.aspire.pdfViewer.PDFViewFragment.onCreateView(PDFViewFragment.java:86) 
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299) 
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595) 
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758) 
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363) 
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149) 
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103) 
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2013) 
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:388) 
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:607) 
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178) 
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1248) 
at android.app.Activity.performStart(Activity.java:6679) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2609) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6077) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) 

はここに私のAndroidManifest宣言

<application 
     android:name="com.aspire.webserviceConstant.AppController" 
     android:allowBackup="true" 
     android:hardwareAccelerated="false" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:largeHeap="true" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme.calender" 
     tools:replace="android:name"> 

であるここで次の変更、android:largeHeap="true"android:hardwareAccelerated="false"

を行っていますこのコード行は、メモリの434035012バイトを割り当てしようとしているビットマップ

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 
    private void showPage(int index) { 
     try { 

      if (pdfRenderer.getPageCount() <= index) { 
       return; 
      } 

      if (null != currentPage) { 
       currentPage.close(); 
      } 

      currentPage = pdfRenderer.openPage(index); 
      releaseBitmap(); 

      bitmapPDF = Bitmap.createBitmap(
        getResources().getDisplayMetrics().densityDpi * currentPage.getWidth()/72, 
        getResources().getDisplayMetrics().densityDpi * currentPage.getHeight()/72, 
        Bitmap.Config.ARGB_8888); 

      currentPage.render(bitmapPDF, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY); 
      imgPdfView.setImageBitmap(bitmapPDF); 
      updateUIData(); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

private void releaseBitmap() { 
    if (bitmapPDF != null) { 
     bitmapPDF.recycle(); 
     bitmapPDF = null; 
    } 
} 
+4

質問を編集し、2行だけでなく、Javaスタックトレース全体を投稿してください。 – CommonsWare

+0

@CommonsWare確かな事を確認してください。 – Kuls

+0

あなたも 'android:hardwareAccelerated =" true "'と試しましたか? –

答えて

4
 bitmapPDF = Bitmap.createBitmap(
       getResources().getDisplayMetrics().densityDpi * currentPage.getWidth()/72, 
       getResources().getDisplayMetrics().densityDpi * currentPage.getHeight()/72, 
       Bitmap.Config.ARGB_8888); 

を作成し、私のコードです。 ARGB_8888のピクセルあたり4バイトでは、10,416 x 10,416ピクセルイメージに相当します。

一般的なAndroid搭載端末は、そのサイズに近い画面解像度を備えていません。あなたはかなり—ことによって、これを削減する場合であっても

あなたはAndroidのガベージコレクタの制限と組み合わせると、Bitmapを解除するあなたの政策に起因するメモリの問題に実行することがあり—以上のような1000×1000個のピクセルに、と言います。

がAndroid APIでPDFを作成した場合を除き、PdfRendererが正しくレンダリングされるとは考えにくいです。そのクラスは印刷プレビュー用であり、任意のPDFコンテンツのレンダリング用ではありません。

任意のPDFをレンダリングする場合は、other PDF rendering optionsを使用してください。 Android図面コードを使用して作成したPDFの印刷プレビューを実行しようとしていて、PdfRendererを使用したい場合は、解像度を下げて、できるだけ少ない数のオブジェクトを使用してください。すべてのページ。

+0

詳細なお返事ありがとうございました。主な関心事は、アプリケーション内にPDFを表示することです。いくつかの種類のスニペットや、この種のビットマップを扱うためにPDFを表示する方法を提案できますか? – Kuls

+0

@KulsDroid:「スニペットやその他の方法でPDFを表示することができますか?」 - あなたを[件名のブログ記事]にリンクしました(https://commonsware.com/blog/2017/01/04 /options-viewing-pdfs.html)。 "とにかくこの種のビットマップを扱う?" - 私は答えでこれをカバーしました。あなたの解像度を減らし、すべてのページに新しいものを割り当てるのではなく、以前に割り当てられたものを再利用することによって、可能な限り少数の 'Bitmap'オブジェクトを使用します。 – CommonsWare