2017-12-14 20 views
0

サーバー(URL)からAdapterのイメージをロードするには、以下のコードを使用します。新モデルのモバイル機器での作業です。しかし、古いモデルはクラッシュし、 "java.lang.OutOfMemoryError"を返します。それはラインAまたはBをエラーとしてマークします。このエラーを回避する方法は?あるいは私の目的を達成するための他の図書館はありますか?助けてくれてありがとう!BaseAdapterメモリ不足エラー

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { 
    ImageView bmImage; 
    ProgressBar progressBar; 

    public DownloadImageTask(ImageView bmImage, ProgressBar progressBar) { 
     this.bmImage = bmImage; 
     this.progressBar = progressBar; 
    } 

    protected Bitmap doInBackground(String... urls) { 
     String urldisplay = urls[0]; 
     Bitmap mIcon11 = null; 
     try { 



      InputStream in = new java.net.URL(urldisplay).openStream(); 
      mIcon11 = BitmapFactory.decodeStream(in); //Line A 

      int resultWidth = mIcon11.getWidth(); 
      int resultHeight = mIcon11.getHeight(); 
      while(resultWidth > 256 && resultHeight > 256) { 
       resultWidth *= 0.5; 
       resultHeight *= 0.5; 
      } 
      mIcon11 = Bitmap.createScaledBitmap(mIcon11, (int) (resultWidth), (int) (resultHeight), true); 

     } catch (OutOfMemoryError e){ 

      byte[] byteArr = new byte[0]; 
      byte[] buffer = new byte[1024]; 
      int len; 
      int count = 0; 


      InputStream in = null; 
      try { 
       in = new java.net.URL(urldisplay).openStream(); 


       while ((len = in.read(buffer)) > -1) { 
        if (len != 0) { 
         if (count + len > byteArr.length) { 
          byte[] newbuf = new byte[(count + len) * 2]; //Line B 
          System.arraycopy(byteArr, 0, newbuf, 0, count); 
          byteArr = newbuf; 
         } 

         System.arraycopy(buffer, 0, byteArr, count, len); 
         count += len; 
        } 
       } 


       final BitmapFactory.Options options = new BitmapFactory.Options(); 
       options.inJustDecodeBounds = true; 
       BitmapFactory.decodeByteArray(byteArr, 0, count, options); 

       options.inSampleSize = calculateInSampleSize(options, 256, 256); 
       options.inPurgeable = true; 
       options.inInputShareable = true; 
       options.inJustDecodeBounds = false; 
       options.inPreferredConfig = Bitmap.Config.ARGB_8888; 


       mIcon11 = BitmapFactory.decodeByteArray(byteArr, 0, count, options); 

      } catch (IOException e1) { 
       e1.printStackTrace(); 
      } 

     } catch (Exception e) { 
      Log.e("Error", e.getMessage()); 
      e.printStackTrace(); 
     } 



     return mIcon11; 
    } 

    protected void onPostExecute(Bitmap result) { 

     bmImage.setImageBitmap(result); 

     progressBar.setVisibility(View.GONE); 
     progressBar.setIndeterminate(false); 
     bmImage.setVisibility(View.VISIBLE); 

    } 


    public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { 
     // Raw height and width of image 
     final int height = options.outHeight; 
     final int width = options.outWidth; 
     int inSampleSize = 1; 

     if (height > reqHeight || width > reqWidth) { 

      // Calculate ratios of height and width to requested height and width 
      final int heightRatio = Math.round((float) height/(float) reqHeight); 
      final int widthRatio = Math.round((float) width/(float) reqWidth); 

      // Choose the smallest ratio as inSampleSize value, this will guarantee 
      // a final image with both dimensions larger than or equal to the 
      // requested height and width. 
      inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; 
     } 


     return inSampleSize; 
    } 

} 
+1

サイズを小さくする。 –

+2

ビットマップがこの例外の原因です。あなたはあなたのサイズを扱うか、グライド、ピカソのような画像ライブラリを使用して作業をする必要があります。 – Umair

+0

アンドロイドマニフェストの 'android:largeHeap =" true "'を追加してください –

答えて

0

高解像度ビットマップの問題。グライドやピカソのように、サイズを減らしたり、ビットマップを読み込むライブラリを使用したりします。 速い修正 - あなたはAndroidManifestで大きなヒープを有効にします:

<application 
     ... 
     android:largeHeap="true" 
+1

私は試してみましたが、うまくいきませんでした! –

+0

https://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize –

+0

たとえば、BitmapOptionsにinSampleSize = 4を使用します –

0

はあなたがGLIDEを使用することができます

android 
{ 
    dexOptions 
{ 
     javaMaxHeapSize "4g" //specify the heap size for the dex process 

    } 
} 
1

あなたのGradleでこれを追加します。

公式ガイドラインLoading Large Bitmapsをお読みください。あなたはRESIZEイメージでなければなりません。

あなたは絶対に にソースを信頼していない限り、それを復号する前 ビットマップの大きさを確認し、java.lang.OutOfMemory例外を回避するには、快適に使用可能なメモリ内 に合った予想通りのサイズの画像データを提供します。

コード構造

  • 同じアスペクト比及び寸法要求幅以上であり、高さ
と原稿からのダウンサンプリングされたビットマップ
public static int calculateInSampleSize(
      BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 

     final int halfHeight = height/2; 
     final int halfWidth = width/2; 

     // Calculate the largest inSampleSize value that is a power of 2 and keeps both 
     // height and width larger than the requested height and width. 
     while ((halfHeight/inSampleSize) >= reqHeight 
       && (halfWidth/inSampleSize) >= reqWidth) { 
      inSampleSize *= 2; 
     } 
    } 

    return inSampleSize; 
}