2012-12-28 41 views
0

我正在創建自己的SlideShow活動,其中有一個ImageView,每當用戶單擊下一個或上一個時,我都會用適當的圖像填充它。幻燈片放映中的OutOfMemory

這些圖片雖然很大,但只要我瀏覽其中的幾個圖片,我就會得到一個OutofMemory,可能是由於我的內存泄漏。

問題是,每次調用一個新圖像時,我都會嘗試清空以前的位圖,因此它被垃圾收集,但無濟於事。

我在這裏錯過了什麼嗎?

我附上我的活動非常簡單的代碼:

public class SlideShowActivity extends Activity { 
    private static final String LOG_TAG = SlideShowActivity.class.getSimpleName(); 

    private Bitmap currentBitmap; 
    private Bitmap mDefaultBitmap; 
    private ImageView imageView; 
    private ImageButton buttonPrev; 
    private ImageButton buttonNext; 
    private int currentImageIndex; 

    private String imguri[] = { "ruta1/imagen1.jpg", "ruta1/imagen2.jpg", "ruta1/imagen3.jpg", "ruta1/imagen4.jpg", "ruta1/imagen5.jpg", "ruta1/imagen6.jpg" }; 

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

     mDefaultBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.noimage); 
     imageView = (ImageView) findViewById(R.id.imageViewCurrentImage); 
     buttonPrev = (ImageButton) findViewById(R.id.imgbuttonprev); 
     buttonNext = (ImageButton) findViewById(R.id.imgbuttonnext); 

     currentImageIndex = 0; 
     setCurrentImage(currentImageIndex); 
     buttonPrev.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       currentImageIndex--; 
       if(currentImageIndex < 0) 
        currentImageIndex = imguri.length-1; 

       setCurrentImage(currentImageIndex); 
      } 
     }); 

     buttonNext.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       currentImageIndex++; 
       if(currentImageIndex == imguri.length) 
        currentImageIndex = 0; 
       setCurrentImage(currentImageIndex); 
      } 
     }); 

    } 

    private void setCurrentImage(int idx) { 

     currentBitmap = null; 
     imageView.setImageBitmap(null); 
     try { 
      currentBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeStream(getAssets().open(imguri[idx])),800, 480, true); 
      imageView.setImageBitmap(currentBitmap); 
     } catch (IOException e) { 
      Log.d(LOG_TAG, "No se pudo abrir el recurso" + imguri[0]); 
      imageView.setImageBitmap(mDefaultBitmap); 
     } 
    } 

} 
+0

圖像尺寸大於告訴你..所以首先計算你的圖像的大小,然後存儲到creatbitmapscale然後使用它....去吧? – QuokMoon

+0

不是我在做的事情嗎? –

回答

0

好了,我不知道,當你改變了很多次的ImageView這種方式的位圖是什麼樣的效果可以採取。但我認爲你應該使用支持庫附帶的ViewPager。這樣,您的實現將會更快,因爲它會自動加載下一個和上一個視圖,並在不再需要時刪除它。而且對用戶來說會更好,因爲他/她可以滑動圖像。

爲了使其更好,你可以使用這個庫,它擴展了ViewPager的功能:

http://viewpagerindicator.com/

+0

謝謝,我會試試這個 –

+0

我試過了,它的確適合我的需求,但是我的內存使用量還在不斷增加,你確定它應該在不再需要的時候自動移除視圖? –

+1

使用PagerAdapter的這個實現:http://developer.android.com/reference/android/support/v13/app/FragmentStatePagerAdapter.html「當有大量頁面時,這個版本的分頁器更有用,工作正常更像是一個列表視圖,當頁面對用戶不可見時,它們的整個片段可能被破壞,只保留該片段的保存狀態,這使得尋呼機可以保存與每個訪問頁面相關的更少的內存, FragmentPagerAdapter的代價是在頁面之間切換時可能會產生更多開銷。「 –

1

這是更好地調用bitmap.recycle()如果不再需要的位圖,這可以使系統更加積極地回收本機內存。

所以setCurrentImage(INT IDX)可以改爲

private void setCurrentImage(int idx) { 
    imageView.setImageBitmap(null); 
    currentBitmap.recycle(); 
    currentBitmap = null; 
    try { 
     Bitmap tempBitmap = BitmapFactory.decodeStream(getAssets().open(imguri[idx])); 
     currentBitmap = Bitmap.createScaledBitmap(tempBitmap, 800, 480, true); 
     tempBitmap.recycle(); 
     imageView.setImageBitmap(currentBitmap); 
    } catch (IOException e) { 
     Log.d(LOG_TAG, "No se pudo abrir el recurso" + imguri[0]); 
     imageView.setImageBitmap(mDefaultBitmap); 
    } 
} 
+0

這沒有解決問題,我的活動不斷增加內存使用量,因爲我切換位圖... –

+0

這應該釋放位圖的內存,如果您的應用程序不斷增加內存,也許你可以使用[MemoryAnalyzer](http:// www.eclipse.org/mat/)來識別泄漏的位置。你可以參考[鏈接](http://android-developers.blogspot.com/2011/03/memory-analysis-for-android.html)瞭解更多信息 – Wilder