1

두 가지 활동이 있습니다. 시작 활동에는 작은 이미지가 있습니다. 각각을 클릭 한 다음 갤러리에서 다른 활동을 ViewPager에서 엽니 다.이미지로드 중 응용 프로그램이 충돌 함 (java.lang.OutOfMemoryError)

갤러리를 열면 아무런 문제없이 이미지가 완벽하게 슬라이드됩니다.

하지만 다시 시작 활동에 가서 갤러리를 다시 열 때, 응용 프로그램은 java.lang.OutOfMemoryError 비트 맵 크기 추락은 내가이 작아, 이미지 크기 다시 시도

VM 예산

을 초과하지만, 도움이되지 않습니다. 그것도 조금 추락했지만 나중에.

갤러리 및 모든 이미지가있는 활동이 삭제되지 않았을 때 생각합니다. 메모리 누수가 있습니다. 갤러리를 들어

나는 AndroidTouchGallery를 사용 : 작업 공간 link on GoogleDrive

내 코드 : link

이이 코드 예제 응용 프로그램입니다. 시작 활동

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


} 

그것은`활동 갤러리

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

가능한 복제본 [이상한 메모리 부족 문제가 비트 맵 객체에 이미지를로드하는 중] (http://stackoverflow.com/questions/477572/strange-out-of-memory) -bit-object-while-load-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

viewItem 어댑터에서 destroyItem을 재정의하고 있는지 확인할 수 있습니다. 이렇게하면 더 이상 화면에 표시되지 않는보기가 제거되어 해당 이미지에 할당 된 메모리가 비워집니다.

예 :

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

또한 비동기 UI 스레드 떨어져 이미지를로드하고, 그래서 당신은 '돈 당신을 위해 처리 메모리에 자신의 할당을 가지고 Picasso 또는 보편적 인 이미지 로더와 같은하여 ImageLoader를 사용하는 것이 좋습니다 것 메모리 예외를 벗어나면 ...

관련 문제