2012-11-23 27 views
5

Possible Duplicate:
java.lang.OutOfMemoryError: bitmap size exceeds VM budget - AndroidViewPager java.lang.OutOfMemoryError: wielkość bitmapy przekracza budżet VM

użyłem ViewPager pokazać zestaw obrazów z folderu zasobów, jeśli moje obrazy były małe coś co działa dobrze,

ale kiedy i zastąpić ją obrazów o wysokiej rozdzielczości, które muszę go mieć w mojej aplikacji, to dał mi ten błąd:

java.lang.OutOfMemoryError: wielkość bitmapy przekracza budżet VM

uWAGA 1:

mam teraz 5 zdjęć w moim kodu do testowania ale w końcu będzie miał około 30 obrazów o wysokiej rozdzielczości,

Note 2:

zastanawiam się dlaczego tak się stało, jestem nowy na Androida i po raz pierwszy użyć klasy viewpager, zanim użyłem klasy galerii w innej aplikacji z ponad 30 obrazami o wysokiej rozdzielczości i żaden wyjątek się nie wydarzył.

Wszelkie porady będą mile widziane, dziękuję

mój kod:

logcat stosu:

FATAL EXCEPTION: main 
    java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:563) 
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:439) 
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:462) 
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:488) 
at com.test.demo.MyPagerAdapter.<init>(MyPagerAdapter.java:42) 
at com.test.demo.MainActivity.onCreate(MainActivity.java:15) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667) 
at android.app.ActivityThread.access$1500(ActivityThread.java:117) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:123) 
at android.app.ActivityThread.main(ActivityThread.java:3687) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:507) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600) 
at dalvik.system.NativeStart.main(Native Method) 

główną działalność

public class MainActivity extends Activity { 
    private ViewPager mMyPager; 
    private MyPagerAdapter mMyPagerAdapter; 

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    mMyPager = (ViewPager) findViewById(R.id.mypages);   
    mMyPagerAdapter = new MyPagerAdapter(this); 
    mMyPager.setAdapter(mMyPagerAdapter); }} 

MyPagerAdapter

public class MyPagerAdapter extends PagerAdapter { 

    private ArrayList<ImageView> mViewsList; 
private Context mContext = null; 

public MyPagerAdapter(Context context) { 
    mContext = context; 
    mViewsList = new ArrayList<ImageView>(); 

    Resources resource = mContext.getResources(); 
    Bitmap bMap1 = BitmapFactory.decodeResource(resource, 
      R.drawable.one); 
    ImageView image1 = new ImageView(mContext); 
    image1.setImageBitmap(bMap1);  
    mViewsList.add(image1); 

    Bitmap bMap2 = BitmapFactory.decodeResource(resource, 
      R.drawable.two); 
    ImageView image2 = new ImageView(mContext); 
    image2.setImageBitmap(bMap2);  
    mViewsList.add(image2); 

    Bitmap bMap3 = BitmapFactory.decodeResource(resource, 
      R.drawable.three); 
    ImageView image3 = new ImageView(mContext); 
    image3.setImageBitmap(bMap3);  
    mViewsList.add(image3); 

    Bitmap bMap4 = BitmapFactory.decodeResource(resource, 
      R.drawable.four); 
    ImageView image4 = new ImageView(mContext); 
    image4.setImageBitmap(bMap4);  
    mViewsList.add(image4); 

    Bitmap bMap5 = BitmapFactory.decodeResource(resource, 
      R.drawable.five); 
    ImageView image5 = new ImageView(mContext); 
    image5.setImageBitmap(bMap5);  
    mViewsList.add(image5); 
       }  

@Override 
public int getCount() { 
    return mViewsList.size(); 
         } 

@Override 
public Object instantiateItem(View view, int position) { 
    View myView = mViewsList.get(position); 
    ((ViewPager) view).addView(myView); 
    return myView; 
       } 

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

@Override 
public void destroyItem(View view, int arg1, Object object) { 
    ((ViewPager) view).removeView((ImageView) object); 
       } 
        } 
+0

Czy widzisz tę kolumnę po prawej stronie StackOverflow, obok pytania, zatytułowanego "Powiązane". Czy widzisz tam tę grupę duplikatów? Jeśli tak, idź tam i czatuj. I doskonal swoje umiejętności wyszukiwania również proszę ... –

+0

@ WebnetMobile.com Widziałem ten post, zanim opublikuję moje pytanie, ale jestem nowy w Androidzie i po raz pierwszy używać klasy viewpager, czy mógłbyś mi wyjaśnić, dlaczego tak się stało? do klasy viewpager lub bitmapy, coz użyłem przed klasą galerii w innej aplikacji z 30 dużymi obrazami wysokiej rozdzielczości i nic się nie stało, dzięki – androidqq6

Odpowiedz

0

Rozmiar twojej bitmapy jest bardzo duży, więc spróbuj skalować mapę bitową przed jej załadowaniem. Składnia do skalowania bitmapy

Bitmap bitmapName= Bitmap.createScaledBitmap(sourceBitmap, width, height, 
         true); 

Jeżeli szerokość i wysokość są wielkości chcesz na obraz, aby być.

0

Twoim problemem jest to, że tworzysz masę map bitowych, zanim naprawdę potrzebujesz.

Wewnątrz metody instantiateView utwórz modele ImageView i załaduj bitmapy i ustaw je tam. Jeśli potrzebujesz, użyj swojej tablicy ArrayList, aby przechowywać ints zasobów, aby wiedzieć, które obrazy załadować, jeśli potrzebujesz. W ten sposób usuwanie śmieci usunie mapy bitowe w razie potrzeby i nie powinno powodować problemów z pamięcią.

+0

jak wspomniałem w powyższym komentarzu, jestem nowy dla Androida i po raz pierwszy użyć zarówno viewpagera jak i mapy bitowej proszę możesz podać swoją odpowiedź w kodzie, dzięki – androidqq6

4

Twój adapter nie powinien być zapisany tak, jak go masz. Powinieneś tylko dekodować bitmapy w metodzie instantiateItem.

private Context context; 
private ArrayList<Integer> mResourceList; 
private Resources resource; 

public MyPagerAdapter(Context context) { 
    this.context = context; 

    resource = context.getResources(); 

    mResourceList = new ArrayList<Integer>();  
    mResourceList.add(R.drawable.one); 
    mResourceList.add(R.drawable.two); 
    mResourceList.add(R.drawable.three); 
    mResourceList.add(R.drawable.four); 
    mResourceList.add(R.drawable.five); 
} 

@Override 
public Object instantiateItem(View view, int position) { 
     ImageView myView = new ImageView(context); 

     Bitmap bitmap = BitmapFactory.decodeResource(resource, mResourceList.get(position)); 
     myView.setImageBitmap(bitmap); 

     ((ViewPager) view).addView(myView); 
     return myView; 
} 

Teraz, trzeba upewnić się, że bitmapy nie są przekroczenia wartości rozmiarze max (2048 px x 2048 px).

Jeśli tak, należy skalować obraz w dół. Można to zrobić, dodając obiekt BitmapFactory.Options do parametrów BitmapFactory.decodeResouce i ustawiając właściwość inSampleSize na potęgę 2. Ustawienie wartości 2 spowoduje próbkowanie do 50%, od 4 do 25% itp.

BitmapFactory.Options options = new BitmapFactory.Options() 
options.inSampleSize = 2 

Bitmap bitmap = BitmapFactory.decodeResource(resource, mResouceList.get(position), options); 

Mam nadzieję, że to pomogło!

+0

użyłem twojego kodu obrazy pojawiają się, potem przewijam pierwszy obraz i drugi obraz do teraz ok, ale kiedy przewijam trzeci obraz, wymuszam zamknięcie z tym wyjątkiem ponownie: java.lang.OutOfMemoryError: rozmiar bitmapy przekracza budżet VM wszelkie porady, dzięki – androidqq6

+0

jak duże są twoje bitmapy? – wdziemia

+0

jego 4000 * 2000 o rozmiarze około 4.5mb każdy obraz – androidqq6

Powiązane problemy