2016-04-11 2 views
0

проекта с ошибкой на GitHub: https://github.com/MediaPortal1/HowToDraw/blob/master/app/src/main/java/com/poltavets/app/setImageBitmap Ошибка, ImageView вызов OutOfMemory

Я имел метод img.setImageResources (R.id.image) в моем проекте, но это offten называют OutOfMemory, когда я использую этот метод часто или изменения ориентация экрана. Я нашел эту статью о загрузке растровых изображений «правильных»: https://developer.android.com/training/displaying-bitmaps/load-bitmap.html копипаст 2 последних методы этой статьи, и изменить свой код от:

 imageView.setImageResource(image); 

К:

Handler handler=new Handler(){ 
      @Override 
      public void handleMessage(Message msg) { 
       if(getRequestedOrientation()==ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) 
        imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), msg.what,100,100)); 
       else imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), msg.what,400,400)); 
      } 
     }; 
     handler.sendEmptyMessage(image); 

Я поставил этот методы Handler и работа была быстрее. И я добавляю условия ориентации, потому что в land-orietation ImageView меньше, а растровое изображение должно иметь меньшее разрешение. Он работал нормально, everithink было нормально. Но я работал с другими деталями в этом проекте (просто добавьте изображения в свой проект) и дважды заново создайте этот проект, а ошибка OutOfMemory появляется снова, когда я начинаю свою деятельность. Прежде чем эта ошибка возникла не всегда, но теперь она возникла ВСЕГДА, когда я запускаю Activity! Как? Я не собираю код этой деятельности? Мои изображения очень низкомоторные. Максимальный размер изображений 200кб. Как изображение размером 100 КБ может вызывать OutOfMemory?

Ошибка:

Process: com.poltavets.app.howtodraw, PID: 28720 java.lang.OutOfMemoryError: Failed to allocate a 35389452 byte allocation with 5482128 free bytes and 5MB until OOM 
    at dalvik.system.VMRuntime.newNonMovableArray(Native Method) 
    at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 
    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:655) 
    at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:488) 
    at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:511) 
    at com.poltavets.app.howtodraw.view.HowTo.decodeSampledBitmapFromResource(HowTo.java:224) 
    at com.poltavets.app.howtodraw.view.HowTo$3.handleMessage(HowTo.java:185) 
    at android.os.Handler.dispatchMessage(Handler.java:111) 
    at android.os.Looper.loop(Looper.java:194) 
    at android.app.ActivityThread.main(ActivityThread.java:5546) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759) 

Код ChangeImage (Ошибка здесь):

public void changeImageSrc(int image,int count,int position,String name) { 
      filename=name+"_"+image+"_"+position; 
      imagenumber=position; 
      if(move!=null || back!=null) { 
       move.setEnabled(false); 
       back.setEnabled(false); 
      } 
      Handler handler=new Handler(){ 
       @Override 
       public void handleMessage(Message msg) { 
        if(getRequestedOrientation()==ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) 
         imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), msg.what,100,100)); 

else imageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), msg.what,400,400)); // OUT OF MEMORY ERROR 
       } 
      }; 
      handler.sendEmptyMessage(image); 

      getSupportActionBar().setTitle(getResources().getString(R.string.title_how_to) + " " + name + ": " + (position+1)+"/"+(count)); 
       if(position==0 || position+1==count){ 
        if(position==0){ 
         findViewById(R.id.backBtn).setEnabled(false); 
         findViewById(R.id.backBtn).setVisibility(View.INVISIBLE); 
        } 
        else { 
         findViewById(R.id.moveBtn).setEnabled(false); 
         findViewById(R.id.moveBtn).setVisibility(View.INVISIBLE); 
         Toast.makeText(getApplicationContext(),getString(R.string.finish),Toast.LENGTH_SHORT).show(); 
        } 
       } 
       else { 
        showNavButtons(); 
       } 
      if(move!=null || back!=null) { 
       move.setEnabled(true); 
       back.setEnabled(true); 
      } 

2 методы из статьи Google:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, 
                 int reqWidth, int reqHeight) { 

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

     // Calculate inSampleSize 
     options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 

     // Decode bitmap with inSampleSize set 
     options.inJustDecodeBounds = false; 
     return BitmapFactory.decodeResource(res, resId, options); 
    } 

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

ответ

0

Я просто ничего не делал. Я восстановил этот проект 3-4 раза, но это не помогло. Но я просто перестраиваю его сейчас без изменений, и он сработал.

+1

Пожалуйста, не ругайтесь в своих ответах. – JAL

+0

кажется, что вам нужно часто чистить/перестраивать проекты при работе с изображениями в приложении. Я включил 3 изображения в приложение (у них было ~ 1.5mb вместе), и приложение разбилось. Независимо от того, что я сделал (мне удалось уменьшить их размер до 50kb), это не помогло. После того, как я очистил/перестроил проект, все внезапно сработало (с меньшими изображениями c). Я предполагаю, что кэшированные изображения использовались перед чисткой/перестройкой, и, таким образом, на самом деле не имело значения, как я оптимизировал изображения. – vanomart

Смежные вопросы