2012-03-19 66 views
2

我做了ViewPager來顯示圖像。當我推進一些頁面時,我得到一個java.lang.OutOfMemoryError: bitmap size exceeds VM budget錯誤。ViewPager與ImageView給「java.lang.OutOfMemoryError:位圖大小超過VM預算」

還有關於這個問題的更多問題,但我沒有找到解決方案(BitMap.Recycle,System.gc()等)。如果您有任何建議或解決方案,請告訴我!

PNG的是628KB,478KB,587KB,132KB,139KB,149KB,585KB(崩潰)。

如果你有其他的解決方案(滾動圖像像頁面)讓我知道!

我的代碼:

package nl.ipear.vngmagazine; 
import android.content.Context; 
import android.graphics.BitmapFactory; 
import android.os.Bundle; 
import android.os.Environment; 
import android.os.Parcelable; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.view.PagerAdapter; 
import android.support.v4.view.ViewPager; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.widget.ImageView; 

public class ShowMagazine2 extends FragmentActivity { 
    private ViewPager myPager; 
    private MyPagerAdapter myPagerAdapter; 

    private static int NUM_PAGES = 15; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.showmagazine); 

     myPager = (ViewPager)findViewById(R.id.viewpager1); 
     myPagerAdapter = new MyPagerAdapter(); 
     myPager.setAdapter(myPagerAdapter); 

     return; 
    } 

    private class MyPagerAdapter extends PagerAdapter{ 
     @Override 
     public int getCount() { 
      return NUM_PAGES; 
     } 

     @Override 
     public Object instantiateItem(View collection, int position) {  
      String location = Environment.getExternalStorageDirectory() + "/MYData/" + "2012-02/"; 

      // Inflate and create the view 
      LayoutInflater layoutInflater = (LayoutInflater) collection.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      View view = layoutInflater.inflate(R.layout.magazinepageview, null); 

      ImageView imageView = (ImageView) view.findViewById(R.id.magazinePageImage); 
      String fileName = String.format("%s%s%02d%s", location, "2012-02_Page_", position + 1, ".png"); 
      Log.v("PNG", fileName); 
      imageView.setImageBitmap(BitmapFactory.decodeFile(fileName)); 

      ((ViewPager) collection).addView(view,0); 

      return view; 
     } 

     @Override 
     public void destroyItem(View collection, int position, Object view) { 
      ((ViewPager) collection).removeView((View) view);   
     } 

     @Override 
     public boolean isViewFromObject(View view, Object object) { 
      return view==((View)object); 
     } 

     @Override 
     public void finishUpdate(View arg0) {} 

     @Override 
     public void restoreState(Parcelable arg0, ClassLoader arg1) {} 

     @Override 
     public Parcelable saveState() { 
      return null; 
     } 

     @Override 
     public void startUpdate(View arg0) {} 
    } 
} 
+0

位圖的大小(像素,不是KB)是多少?並在每個尺寸崩潰? (也有這個問題,但我需要更多的信息) – Bigflow 2012-03-19 15:16:04

+0

感謝您的回覆,圖片是aprox 1240x1584。這些圖像是從PDF生成的,適用於手機和平板電腦! – Hans 2012-03-19 15:33:45

+0

你嘗試了更小的圖像嗎?例如300 x 300.因爲可以以較小的塊「剪切」圖像,並對這些塊進行解碼,然後您可以將其顯示爲完整圖像。 – Bigflow 2012-03-20 07:20:01

回答

1

這樣看來,你的ViewPager加載的位圖,但是當你通過滾動不釋放任何。

我建議你限制當前可查看頁面任一側的頁數,這將允許系統清理其他頁面中的位圖。

確保當您的活動/片段被破壞時回收Bitmaps以幫助解決OOM問題。

+0

如何限制頁面?目前有三個圖像加載。 – Hans 2012-03-19 18:32:37

+0

因爲我在destroyItem中釋放內存,所以必須存在內存泄漏或Android中的錯誤。我真的覺得我需要使用其他方法,因爲我無法修復錯誤。 – Hans 2012-03-19 18:47:14

+0

@Hans嗨,即使我遇到了同樣的問題。你是如何最終解決它的? – mango 2015-02-25 09:07:33

1

是遵循Mimminito。我建議2頁,因爲對於3頁來回渲染同樣快速。

現在,如果你需要圖像沒有滯後和圖像在互聯網上。確保你下載它並放入internalStorageDevice中,如果存在,就重新使用它。

我的最佳答案可能是內存泄漏問題。這個新的答案是內存泄漏的一個可能原因是由於圖像的高度和寬度。

private byte[] resizeImage(byte[] input) { 

    if (input == null) { 
     return null; 
    } 

    Bitmap bitmapOrg = BitmapFactory.decodeByteArray(input, 0, input.length); 

    if (bitmapOrg == null) { 
     return null; 
    } 

    int height = bitmapOrg.getHeight(); 
    int width = bitmapOrg.getWidth(); 
    int newHeight = 250; 

    float scaleHeight = ((float) newHeight)/height; 

    // creates matrix for the manipulation 
    Matrix matrix = new Matrix(); 
    // resize the bit map 
    matrix.postScale(scaleHeight, scaleHeight); 

    // recreate the new Bitmap 
    Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, 
      width, height, matrix, true); 

    bitmapOrg.recycle(); 

    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
    resizedBitmap.compress(CompressFormat.PNG, 0 /*ignored for PNG*/, bos);    

    resizedBitmap.recycle(); 

    return bos.toByteArray();    
}  

此頂層代碼用於重新調用位圖「newHeight」是給位圖的新高度。

現在,如果這不起作用,我現在100%確定OP必須重載ViewPager,並使用更多的android內存可以處理的視圖。對此的解決方案是使用ViewFlipper並使用上面所述的答案。

+0

即使setOffscreenPageLimit設置爲1,圖像也會存儲在外部存儲器中,但會產生內存錯誤!? – Hans 2012-03-19 18:44:59

+0

好吧我認爲如果尺寸太大,縮放可能會出錯。我只會在一頁上重新發布我的答案測試中的代碼。然後,將其設置爲onflicklistener,以便每當它被輕彈時,就會在第二頁上呈現一個新圖像。 – sdfwer 2012-03-19 19:26:29

1

嘗試和縮小你的位圖,它確實解決了這個問題,這裏是你如何做到這一點..

BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(filename, options); 
     options.inJustDecodeBounds = false; 
     options.inSampleSize = 2; 

     bitmap = BitmapFactory.decodeFile(filename, options); 
     if (bitmap != null && exact) { 
      bitmap = Bitmap.createScaledBitmap(bitmap, width, height, false); 
     } 

調整到任何你希望它是,例如,樣本大小4,8等

+0

當我按比例縮小圖像時,它將起作用,但用戶必須能夠放大。當縮放圖像時這會起作用嗎? – Hans 2012-03-19 15:32:39

+0

通過改變樣本大小自己嘗試一下,只要您對圖像質量滿意,就會很好。 – 2012-03-19 15:45:10

+0

我希望當用戶放大時可以「重新加載」圖像。 – Hans 2012-03-19 18:30:07

0

調用System.gc()中的OnCreate()

+1

不要這樣做。請不要嘗試手動控制GC。如果你不這樣做,你很有可能會得到更糟糕的結果。 – 2014-05-05 08:15:00

1

找到了答案在這裏:Android:java.lang.OutOfMemoryError: Failed to allocate a 23970828 byte allocation with 2097152 free bytes and 2MB until OOM

只是在你的應用程序標記添加android:hardwareAccelerated="false"android:largeHeap="true"內AndroidManifest:

<application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme" 
     android:hardwareAccelerated="false" 
     android:largeHeap="true"> 
相關問題