1

У меня есть два вида деятельности. В стартовой деятельности есть небольшие изображения. Нажмите каждый из них, а затем откройте другое действие с помощью галереи по адресу ViewPager.Ошибка приложения при загрузке изображения (java.lang.OutOfMemoryError)

При открытии Галереи он полностью помещает изображения без проблем.

Но когда я возвращаюсь к стартовому деятельности и открыть галерею, приложение разбился с размером java.lang.OutOfMemoryError растровый превышает Vm бюджет

Я пытался изменить размер изображения, получить его меньше, но это не помогает. Он также разбился, но немного позже.

Я думаю, что когда действие с Галереей и все изображения не были уничтожены. У него есть утечка памяти.

Для галереи я использую AndroidTouchGallery: link

Это пример приложения с помощью этого кода: рабочее пространство link on GoogleDrive

Мой код. Начало деятельности

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 


     ArrayList<String> list_big_images = new ArrayList<String>(); 
     list_big_images.add("http://www.oa.edu.ua/assets/images/n/2013/small/evropeyska_misiya1_s.jpg"); 
     list_big_images.add("http://www.oa.edu.ua/assets/images/n/2013/small/evropeyska_misiya2_s.jpg"); 
     list_big_images.add("http://www.oa.edu.ua/assets/images/n/2013/small/evropeyska_misiya3_s.jpg"); 

     ArrayList<String> list_big_images_big = new ArrayList<String>(); 
     list_big_images_big.add("http://www.oa.edu.ua/assets/images/n/2013/big/evropeyska_misiya1_b.jpg"); 
     list_big_images_big.add("http://www.oa.edu.ua/assets/images/n/2013/big/evropeyska_misiya2_b.jpg"); 
     list_big_images_big.add("http://www.oa.edu.ua/assets/images/n/2013/big/evropeyska_misiya3_b.jpg");  


     //get Screen size 
     int width; //Display width 
     int height; //Display height 

     if ( Integer.valueOf(android.os.Build.VERSION.SDK_INT) > 13) { 
       Display display = getWindowManager().getDefaultDisplay(); 
        Point size = new Point(); 
        display.getSize(size); 
        width = size.x; 
        height = size.y; 
     } else { 
      Display display = getWindowManager().getDefaultDisplay(); 
      width = display.getWidth(); 
      height = display.getHeight(); 
     } 

     ImageView[] imageViewArray = new ImageView[list_big_images.size()]; 
     for (int i = 0; i<list_big_images.size(); i++) 
      try { 
        String url = list_big_images.get(i); 
        //url_img_small.add(text); 
        // Let's create the missing ImageView 
        imageViewArray[i] = new ImageView(MainActivity.this);        

        // Now the layout parameters, these are a little tricky at first 
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(width/3, width/3); 
        imageViewArray[i].setScaleType(ImageView.ScaleType.FIT_XY); 
        imageViewArray[i].setId(i + 1); // BELOW id 0 doesn't work 
        imageViewArray[i].setPadding(0, 5, 5, 0); 
        if (i > 0) { 
         if (i % 3 == 0){ 
          params.addRule(RelativeLayout.BELOW, imageViewArray[i - 3].getId()); 
         } 
         else { 
          params.addRule(RelativeLayout.RIGHT_OF, imageViewArray[i - 1].getId()); 
          if (i>2) 
           params.addRule(RelativeLayout.BELOW, imageViewArray[i - 3].getId()); 
         }; 
        } 

        Drawable drawable = grabImageFromUrl(url); 
        imageViewArray[i].setImageDrawable(drawable); 

        final ArrayList<String> list_big_images_big2 = list_big_images_big; 
        final int pos = i; 
        imageViewArray[i].setOnClickListener(new OnClickListener() 

         { 
          @Override 
          public void onClick(View v) { 
           System.out.println(v.getId()); 
           Intent intent = new Intent(v.getContext(), Full_Image_Activity.class); 
           intent.putExtra("ArrayImgBig", list_big_images_big2); 
           intent.putExtra("pos", pos+1); 
           startActivityForResult(intent, 0); 

          } 
         }); 

        // Let's get the root layout and add our ImageView 
        RelativeLayout layout = (RelativeLayout) findViewById(R.id.moreImages); 
        layout.addView(imageViewArray[i], params); 
       } 
       catch (Exception e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
     } 

    //load Image from Url 
    private Drawable grabImageFromUrl(String url) throws Exception { 
     return Drawable.createFromStream(
       (InputStream) new URL(url).getContent(), "src"); 
    } 


} 

It`s активность с галереей

public class Full_Image_Activity extends Activity { 

    ArrayList <String> ArrayImgBig = null; 
    int id_news; 
    private GalleryViewPager mViewPager; 
    int pos ; //Picture Position 
    UrlPagerAdapter pagerAdapter; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_full__image); 

     ArrayImgBig = getIntent().getExtras().getStringArrayList("ArrayImgBig"); 
     pos = getIntent().getExtras().getInt("pos"); 

     UrlPagerAdapter pagerAdapter = new UrlPagerAdapter(Full_Image_Activity.this, ArrayImgBig); 
     pagerAdapter.setOnItemChangeListener(new OnItemChangeListener() 
     { 
      @Override 
      public void onItemChange(int currentPosition) 
      { 
       Toast.makeText(Full_Image_Activity.this, "Current item is " + currentPosition, Toast.LENGTH_SHORT).show(); 
      } 


     }); 

     mViewPager = (GalleryViewPager)findViewById(R.id.viewer); 
     mViewPager.setOffscreenPageLimit(3); 
     mViewPager.setAdapter(pagerAdapter); 
     mViewPager.setCurrentItem(pos); 
    } 


    @Override 
    public void onBackPressed() { 
     this.finish(); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     pagerAdapter = null; 
     mViewPager = null; 
     System.gc(); 
    } 
} 

Я использую метод onDestoy. Но это не помогает. Все одно и то же.

Журнал:

11-27 15:39:59.239: I/System.out(471): 1 
11-27 15:40:00.248: D/dalvikvm(471): GC_EXTERNAL_ALLOC freed 1638K, 48% free 4736K/9031K, external 15372K/16229K, paused 116ms 
11-27 15:40:00.879: D/dalvikvm(471): GC_EXTERNAL_ALLOC freed 35K, 48% free 4742K/9031K, external 17773K/18518K, paused 100ms 
11-27 15:40:02.519: I/dalvikvm(471): Jit: resizing JitTable from 2048 to 4096 
11-27 15:40:04.959: W/KeyCharacterMap(471): No keyboard for id 0 
11-27 15:40:04.959: W/KeyCharacterMap(471): Using default keymap: /system/usr/keychars/qwerty.kcm.bin 
11-27 15:40:05.159: D/dalvikvm(471): GC_EXPLICIT freed 155K, 49% free 4654K/9031K, external 20410K/21124K, paused 111ms 
11-27 15:40:05.738: D/dalvikvm(471): GC_EXPLICIT freed 3K, 49% free 4652K/9031K, external 20410K/21124K, paused 223ms 
11-27 15:40:10.703: I/System.out(471): 2 
11-27 15:40:11.748: D/dalvikvm(471): GC_EXTERNAL_ALLOC freed 43K, 48% free 4754K/9031K, external 20410K/21124K, paused 106ms 
11-27 15:40:11.998: D/dalvikvm(471): GC_EXTERNAL_ALLOC freed 4K, 48% free 4780K/9031K, external 23046K/23760K, paused 112ms 
11-27 15:40:12.048: E/dalvikvm-heap(471): 1334000-byte external allocation too large for this process. 
11-27 15:40:12.208: E/GraphicsJNI(471): VM won't let us allocate 1334000 bytes 
11-27 15:40:12.208: D/dalvikvm(471): GC_FOR_MALLOC freed 0K, 48% free 4780K/9031K, external 23046K/23760K, paused 87ms 
11-27 15:40:12.229: D/skia(471): --- decoder->decode returned false 
11-27 15:40:12.238: W/dalvikvm(471): threadid=23: thread exiting with uncaught exception (group=0x40015560) 
11-27 15:40:12.248: E/AndroidRuntime(471): FATAL EXCEPTION: AsyncTask #5 
11-27 15:40:12.248: E/AndroidRuntime(471): java.lang.RuntimeException: An error occured while executing doInBackground() 
11-27 15:40:12.248: E/AndroidRuntime(471): at android.os.AsyncTask$3.done(AsyncTask.java:200) 
11-27 15:40:12.248: E/AndroidRuntime(471): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
11-27 15:40:12.248: E/AndroidRuntime(471): at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
11-27 15:40:12.248: E/AndroidRuntime(471): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
11-27 15:40:12.248: E/AndroidRuntime(471): at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
11-27 15:40:12.248: E/AndroidRuntime(471): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
11-27 15:40:12.248: E/AndroidRuntime(471): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
11-27 15:40:12.248: E/AndroidRuntime(471): at java.lang.Thread.run(Thread.java:1019) 
11-27 15:40:12.248: E/AndroidRuntime(471): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
11-27 15:40:12.248: E/AndroidRuntime(471): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 
11-27 15:40:12.248: E/AndroidRuntime(471): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:470) 
11-27 15:40:12.248: E/AndroidRuntime(471): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:525) 
11-27 15:40:12.248: E/AndroidRuntime(471): at ru.truba.touchgallery.TouchView.UrlTouchImageView$ImageLoadTask.doInBackground(UrlTouchImageView.java:102) 
11-27 15:40:12.248: E/AndroidRuntime(471): at ru.truba.touchgallery.TouchView.UrlTouchImageView$ImageLoadTask.doInBackground(UrlTouchImageView.java:1) 
11-27 15:40:12.248: E/AndroidRuntime(471): at android.os.AsyncTask$2.call(AsyncTask.java:185) 
11-27 15:40:12.248: E/AndroidRuntime(471): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
11-27 15:40:12.248: E/AndroidRuntime(471): ... 4 more 
+0

Возможный дубликат [Незначительная проблема с памятью при загрузке изображения в объект Bitmap] (http://stackoverflow.com/questions/477572/strange-out-of-memory -issue-while-load-an-image-to-a bitmap-object) – tcooc

ответ

0

редактировать ваш OnDestroy к следующему:

@Override 
public void onDestroy() { 
    pagerAdapter = null; 
    mViewPager = null; 
    System.gc(); 
    super.onDestroy(); 
} 

или поместить код в OnPause()

+0

попытайтесь отредактировать onDrestroy и попытайтесь использовать onPause(). Но у меня такая же ошибка. Обновить вопрос. Добавить журнал ошибок. – Volodymyr

0

Я рекомендую вам использовать Universal Image Loader библиотеку, так что вы можете предотвратить ваше приложение от java.lang.OutOfMemoryError ошибок. Вот github link. Проверь это.

Кроме того, вы можете перерабатывать объекты растровых изображений, если они больше не используются. Вам не нужно звонить System.gc(), чтобы освободить память. Если вы хотите освободить память, вы должны вызвать метод recycle().

С другой стороны, существует еще один способ избежать этого исключения. Вы можете изменить свой образ. Этот путь был объяснен в предыдущем потоке. Вот link

Надеюсь, это поможет!

0

Вы можете проверить, что в вашем адаптере viewpager вы являетесь основным элементом destroyItem. Это приведет к удалению представления, когда оно больше не отображается на экране, тем самым освобождая память, выделенную для этого изображения.

пример:

@Override 
    public void destroyItem(ViewGroup container, int position, Object object) { 
     container.removeView((View) object); 
    } 

Я также рекомендую вам использовать imageloader как Picasso или универсальный загрузчик изображений для загрузки изображений асинхронно от Ui нити, и иметь их распределение в памяти обрабатывается для вас, чтобы вы не» t получить из памяти исключения ...

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