2016-09-27 27 views
2

ImageViewをプログラムで追加するLinearレイアウトが2つあります。imageView.setImageBitmap(ビットマップ)を使用しています。画像を設定します。そして、メモリ不足エラーが発生します。 https://developer.android.com/training/displaying-bitmaps/process-bitmap.htmlを読んだ後で、私は非同期タスクでイメージビットマップを設定することにしましたが、私はまだ同じエラーを受け取ります。このエラーは何度か一致しません。時には私はそれを取得しません。これは私のAsyncタスククラスのコードです。致命的な例外:非同期タスクAndroidのdoInBackground()メソッドのjava.lang.OutOfMemoryError?

class SetImageInAsync extends AsyncTask<String, String, ImageWrapper>{ 
    ImageView imageView; 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     imageView = new ImageView(DisplayContent.this); 
     LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); 
     layoutParams.setMargins(16,16,16,16); 
     imageView.setLayoutParams(layoutParams); 
     imageView.setScaleType(ImageView.ScaleType.FIT_XY); 
     web_linearLayout.addView(imageView); 

    } 

    @Override 
    protected ImageWrapper doInBackground(String... params) 
    { 
     Uri image_uri = Uri.fromFile(new File("/sdcard/rreadyreckoner_images/" + params[0])); 
     Bitmap mBitmap = null; 
     try { 
      mBitmap = MediaStore.Images.Media.getBitmap(DisplayContent.this.getContentResolver(), image_uri); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     ImageWrapper w = new ImageWrapper(); 
     w.bitmap = mBitmap; 
     w.filename = params[0]; 
     return w; 
    } 

    @Override 
    protected void onPostExecute(final ImageWrapper imgWR) { 

     Bundle extras = getIntent().getExtras(); 
     final String subcategory = extras.getString("subcategory"); 
     imageView.setAdjustViewBounds(true); 
     imageView.setScaleType(TouchImageView.ScaleType.FIT_CENTER); 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 
      imageView.setCropToPadding(false); 
     } 
     imageView.setImageBitmap(imgWR.bitmap); 
     imageView.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) 
      { 
       Intent intent = new Intent(DisplayContent.this,DisplayImage.class); 
       intent.putExtra("filename",imgWR.filename); 
       intent.putExtra("subcategory",subcategory); 
       startActivity(intent); 


      } 
     }); 


    } 
} 

そして、これは私が取得エラーログです: -

09-27 15:10:07.587 10366-10898/com.inevitable.org.tab_sample E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1 
Process: com.inevitable.org.tab_sample, PID: 10366 
java.lang.RuntimeException: An error occured while executing doInBackground() 
at android.os.AsyncTask$3.done(AsyncTask.java:300) 
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) 
at java.util.concurrent.FutureTask.setException(FutureTask.java:222) 
at java.util.concurrent.FutureTask.run(FutureTask.java:242) 
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 
at java.lang.Thread.run(Thread.java:841) 
Caused by: java.lang.OutOfMemoryError 
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 
at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:736) 
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:712) 
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:750) 
at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:830) 
at com.inevitable.org.tab_sample.DisplayContent$SetImageInAsync.doInBackground(DisplayContent.java:236) 
at com.inevitable.org.tab_sample.DisplayContent$SetImageInAsync.doInBackground(DisplayContent.java:216) 
at android.os.AsyncTask$2.call(AsyncTask.java:288) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)  
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)  
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)  
at java.lang.Thread.run(Thread.java:841)  

私はプログラミングに新しいですので、任意のヘルプや提案がappreciated.Thankあなたです。

+0

この行に問題があります。** mBitmap = MediaStore.Images.Media.getBitmap(DisplayContent.this.getContentResolver()、image_uri); **これをチェックしてくださいhttp://stackoverflow.com/questions/11381113/ mediastore-images-media-getbitmap-and-out-of-memory-error –

+0

ありがとう@brahmyadigopula私はこのリンクを試しました。http://tutorials-android.blogspot.in/2011/11/outofmemory-exception-when-decodingあなたの提案されたlink.Nowからのhtmlは表示されますが、それらは歪んでいます。 – AndroidNewBee

+0

そのブログをもう一度読んでください。** samplesize ** propertyはビットマップを取り、その高さと幅を元のサイズの20%(1/5)に縮小します。 inSampleSize N(この例ではN = 5)の値が大きいほど、ビットマップのサイズが小さくなります。 –

答えて

3

ビットマップが大きすぎてOOMを引き起こしている可能性があります。スレッドの問題ではありません。

これは良い出発点です。自分自身を含め、多くのAndroid開発者にとって有益なことです。

Loading Large Bitmaps Efficiently

+0

@AndroidNewBeeまた、Bitmap.Config.ARGB_8888とBitmap.Config.RGB_565の使用の違いは大きく、メモリ消費に大きな影響を与えます。私はそれが私を助けたので、それらの部分を注意深く読むことをお勧めします。幸運:) – Lev

+0

ありがとう@Lev。あなたは私が動的に私のJavaコードからそれを追加しているので、私はイメージにどのリソースIDを提供すべきか教えてください。 – AndroidNewBee

1

@brahmyadigopulaにより示唆されるように、私は、この例http://tutorials-android.blogspot.in/2011/11/outofmemory-exception-when-decoding.htmlからのサンプルコードを使用します。

// Read bitmap 
    public Bitmap readBitmap(Uri selectedImage) { 
     Bitmap bm = null; 

     // First decode with inJustDecodeBounds=true to check dimensions 
     final BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inJustDecodeBounds = true; 



     AssetFileDescriptor fileDescriptor =null; 
     try { 
      fileDescriptor = this.getContentResolver().openAssetFileDescriptor(selectedImage,"r"); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 
     finally{ 
      try { 
       bm = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options); 

       // Calculate inSampleSize 
       options.inSampleSize = calculateInSampleSize(options,200, 200); 

       // Decode bitmap with inSampleSize set 
       options.inJustDecodeBounds = false; 
       bm = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(), null, options); 


       fileDescriptor.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     return bm; 
    } 

そして@Levによって示唆されるようにhttps://developer.android.com/training/displaying-bitmaps/load-bitmap.htmlで次のコードを使用して、サンプルサイズで算出。

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; 
} 

そして、次のようにそれを使用: -

Uri image_uri = Uri.fromFile(new File("/sdcard/rreadyreckoner_images/" + params[0])); 

      Bitmap mBitmap = readBitmap(image_uri); 

は、あなたとあなたの@Lev guidance.Keepまで良い仕事のために@brahmyadigopulaをありがとうございます。

+0

私はあなたの試行と成功した結果に投票しました。 –

+0

おかげで。ハッピーコーディング。 – AndroidNewBee

+0

@AndroidNewBee良い仕事の男、良い仕事。サービスにはうれしいです。 – Lev

関連する問題