Autore Topic: ennesimo problema bitmap size exceeds VM budget  (Letto 433 volte)

Offline elfo83

  • Utente normale
  • ***
  • Post: 287
  • Respect: +23
    • Mostra profilo
  • Sistema operativo:
    Mac OS 10.8.2
ennesimo problema bitmap size exceeds VM budget
« il: 24 Gennaio 2013, 04:40:44 CET »
0
Ciao a tutti vi propongo l'ennesimo problema di questo tipo e vi garantisco che ho visto le altre discussioni sul forum riguardanti questo tema  O:-)
Comincio dalla fine, l'errore che viene fuori è il famoso...

Codice (Java): [Seleziona]
01-24 03:07:24.230: E/AndroidRuntime(1122): FATAL EXCEPTION: main
01-24 03:07:24.230: E/AndroidRuntime(1122): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.graphics.Bitmap.nativeCreate(Native Method)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.graphics.Bitmap.createBitmap(Bitmap.java:477)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.graphics.Bitmap.createBitmap(Bitmap.java:444)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:349)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:488)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:463)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:326)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:349)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:375)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at com.qriket.qriket.scan.spinview.scaleImage(spinview.java:1917)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at com.qriket.qriket.scan.spinview.yesPlayBtnClicked(spinview.java:1037)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at com.qriket.qriket.scan.spinview.access$28(spinview.java:989)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at com.qriket.qriket.scan.spinview$8.onClick(spinview.java:331)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.view.View.performClick(View.java:2534)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.view.View$PerformClick.run(View.java:9210)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.os.Handler.handleCallback(Handler.java:587)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.os.Handler.dispatchMessage(Handler.java:92)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.os.Looper.loop(Looper.java:123)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at android.app.ActivityThread.main(ActivityThread.java:3652)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at java.lang.reflect.Method.invokeNative(Native Method)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at java.lang.reflect.Method.invoke(Method.java:507)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:862)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
01-24 03:07:24.230: E/AndroidRuntime(1122):     at dalvik.system.NativeStart.main(Native Method)

Questo è il secondo problema (che ho scoperto proprio ieri) oltre a quello ho postato in questo topic: http://www.anddev.it/index.php/topic,9915.0.html
La cosa curiosa è che sul modello di telefono Samsung GalaxyS funziona tutto bene, mentre sul Sony ericsson eXperia mi da il sopracitato problema.

Vi posto direttamente tutta le parti coinvolte nel problema della mia Attivity:
Codice (Java): [Seleziona]
public class spinview extends Activity{
......

        private VideoView videoRock;
        private RelativeLayout spin_videobtncontainer;
    private Button spin_pick1;
    private Button spin_pick2;
    private Button spin_pick3;
    private ImageView videoCover;
    private boolean firstVideoLoad;
    private boolean firstTimeYes;
        private boolean played;
        private boolean loseAnimation;
        private boolean doubleGame;
    private ImageView videoWinIcon;
    private TextView videoWinAmount;
    private TextView patchTop;
    private ImageView rock1;
    private ImageView rock2;
    private ImageView rock3;
    private LinearLayout rockAnimContainer;
    private Bitmap resizeBit;
       
   
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
                .....
               
            videoRock = (VideoView)findViewById(R.id.spinview_pickrock);
            setVideoRock();
           
                spin_videobtncontainer=(RelativeLayout)findViewById(R.id.spin_videobtncontainer);
            videoCover=(ImageView)findViewById(R.id.spin_covervideo);
           
           
            patchTop=(TextView)findViewById(R.id.spin_patchtop);
            patchTop.setBackgroundColor(Color.rgb(196, 222, 220));
           
            spin_pick1=(Button)findViewById(R.id.spin_pick1);
                spin_pick2=(Button)findViewById(R.id.spin_pick2);
                spin_pick3=(Button)findViewById(R.id.spin_pick3);
                disablePickBtn();
               
                setVideoListener();

                firstVideoLoad=true;
                firstTimeYes=true;
                played=false;
                doubleGame=false;
                videoWinIcon=(ImageView)findViewById(R.id.spin_videowinicon);
                videoWinAmount=(TextView)findViewById(R.id.spin_videowinamount);
               
                rock1=(ImageView)findViewById(R.id.spin_rockwinlose1);
                rock2=(ImageView)findViewById(R.id.spin_rockwinlose2);
                rock3=(ImageView)findViewById(R.id.spin_rockwinlose3);
                rockAnimContainer=(LinearLayout) findViewById(R.id.spin_rockwinlose);

                loseAnimation=false;
               
                .......
               
        private void setVideoListener()
        {
                videoRock.setOnCompletionListener(new OnCompletionListener(){

                        @Override
                        public void onCompletion(MediaPlayer mp) {
                               
                               
                                if(firstVideoLoad)
                                {
                                       
                                        setAlphaEnd(false);
                                        int imgId=R.drawable.bgvideoend;
                                        scaleImage(imgId);
                                       
                                        enablePickBtn();

                                }
                               
                                else if(!firstVideoLoad && played)
                                {
                                        Log.d("FINITO CARICAMENTO E HO GIOCATO","OK");
                               
                                                disablePickBtn();
                                }
                               
                                else if(!firstVideoLoad && !played)
                                {
                                        Log.d("FINITO CARICAMENTO E DEVO ANCORA GIOCARE","OK");
                                        setAlphaEnd(false);

                                        //Bitmap bi =   BitmapFactory.decodeResource(getResources(), R.drawable.bgvideoend);
                                        int imgId=R.drawable.bgvideoend;
                                        scaleImage(imgId);
                                        enablePickBtn();
                                }
                       

                        }
                       
                       
                       
                       
                });
                videoRock.setOnPreparedListener(new OnPreparedListener(){

                        @Override
                        public void onPrepared(MediaPlayer mediaPlayer) {
                                Log.d("ON PREPARED","OK");

                               
                                int mediaWidth=videoRock.getWidth();
                                int mediaHeight=videoRock.getHeight();
               

                                float videoRatio=(float)mediaWidth/(float)mediaHeight;

                               
                                Display display=getWindowManager().getDefaultDisplay();
                                int screenWidth=display.getWidth();
                                int screenHeight=display.getHeight();
                               

                                float screenRatio = (float) screenWidth/ (float) screenHeight;
                       

                                android.view.ViewGroup.LayoutParams lp = videoRock.getLayoutParams();
                                if(videoRatio > screenRatio)
                                {
                                        lp.width=screenWidth;
                                        lp.height=(int)((float) screenWidth / videoRatio)+5;
                                }
                                else
                                {
                                        lp.width=(int) (videoRatio *(float)screenHeight);
                                        lp.height=screenHeight;
                                }
                               
                               
                                videoRock.setLayoutParams(lp);
                               
                       

                        }
                       
                });
       
       
    @Override
    public void onDestroy()
    {
        super.onDestroy();
        unbindDrawables(findViewById(R.id.spinview));
        System.gc();
    }
   
        protected void unbindDrawables(View view) {
                if(view==null)
                        return;
        if(view instanceof ImageView)
        {
                if(((ImageView) view).getDrawable()!=null)
                        ((ImageView) view).getDrawable().setCallback(null);
        }
        if (view.getBackground() != null) {
                view.getBackground().setCallback(null);
        }
        if (view instanceof ViewGroup) {
            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
                unbindDrawables(((ViewGroup) view).getChildAt(i));
            }
            if(!((view instanceof ListView) || ( view instanceof Spinner)))
                ((ViewGroup) view).removeAllViews();
           
        }
    }
       

       
        private void pick()
        {
                resizeBit.recycle();
               
                setAlphaBetween(false);
               

                final int imgId=R.drawable.bgvideobetween;
                scaleImage(imgId);
               
                doublePlayCount++;
                bonustype=1;
                played=true;
                firstVideoLoad=false;
                disablePickBtn();
                callAppBet();
        }
        private void setAlphaBetween(boolean cover)
        {
               
                if(cover)
                {
                        Drawable alpha = getResources().getDrawable(R.drawable.bgvideobetween);
                        alpha.setAlpha(0);
                        videoCover.setImageDrawable(alpha);
                }
                else if(!cover)
                {
                        Drawable alpha = getResources().getDrawable(R.drawable.bgvideobetween);
                        alpha.setAlpha(255);
                        videoCover.setImageDrawable(alpha);
                }
        }

        private void initVideoAlpha(final boolean cover)
        {
                videoRock.postDelayed(new Runnable(){
                        @Override
                        public void run()
                        {
                                setAlphaBetween(cover);
                        }
                       
                }, 150);
        }
        private void setAlphaEnd(boolean cover)
        {
               
                if(cover)
                {
                        Drawable alpha = getResources().getDrawable(R.drawable.bgvideoend);
                        alpha.setAlpha(0);
                        videoCover.setImageDrawable(alpha);
                }
                else if(!cover)
                {
                        Drawable alpha = getResources().getDrawable(R.drawable.bgvideoend);
                        alpha.setAlpha(255);
                        videoCover.setImageDrawable(alpha);
                }
        }
        private void startVideo()
        {
                Handler handler = new Handler();
            Runnable delay=new Runnable()
            {
                public void run()
                {
                    Log.d("VIDEO START","ok");
                    initVideoAlpha(true);


                }
            };
            handler.postDelayed(delay, 800);
        }
        private void videoRockBg()
        {
                Handler handler = new Handler();
                Runnable runnable=new Runnable()
                {
                        @Override
                        public void run()
                        {
                                setVideoRock();
                        }
                };
                handler.postDelayed(runnable, 200);
               
        }
       
       
        private void scaleImage(int idImg)
        {

                Display display=getWindowManager().getDefaultDisplay();
               
                int screenWidth=display.getWidth();
                int screenHeight=display.getHeight();
                float screenRatio=(float) screenWidth/(float)screenWidth;
               
                Bitmap bitmap= BitmapFactory.decodeResource(getResources(), idImg);
               
               
                int imgWidth=bitmap.getWidth();
                int imgHeight=bitmap.getHeight();
               

                float imgRatio=(float)imgWidth/(float)imgHeight;
               
                if(imgRatio > screenRatio)
                {
                        imgWidth=screenWidth;
                        imgHeight=(int)((float) screenWidth / imgRatio);
                }
                else
                {
                        imgWidth=(int) (imgRatio *(float)screenHeight);
                        imgHeight=screenHeight;
                }
               
       
               

                resizeBit=Bitmap.createScaledBitmap(bitmap, imgWidth, imgHeight, false);
                videoCover.setImageBitmap(resizeBit);
                videoCover.setScaleType(ImageView.ScaleType.FIT_XY);
               
                if(bitmap!=null)
                        bitmap.recycle();

        }

       

}

Praticamente ho un VideoView e due immagini che corrispondono esattamente al primo ed ultimo frame del filmato che carico nel videoView. Questo perché nel momento in cui carico il filmato, onde evitare la schermata nera, piazzo la prima immagine prima che il video parta, poi gli setto la trasparenza in modo tale che vedo il video caricato nel videoView e quando il filmato finisce, tolgo la trasparenza all'immagine e le setto un nuovo background. Il problema è questo: le dimensioni dell'immagine che carico alla fine e quelle di videoView non corrispondono esattamente. Dovrei quindi calcolare le dimensioni del display e ricalcolarmi le misure della mia videoView e della mia immagine in maniera tale da essere uguali. Quando vado a ricalcolare le misure e faccio partire la mia activity, esce fuori quell'errore. Premetto che ho letto tutta la guida su Android Developer, quella in cui viene spiegato come si dovrebbero caricare e ridimensionare le immagini. Ho provato anche con la creazione di
BitmapFactory.Option option = new BitmapFactory.option();
option.inJustB...=true;
option.inSimpleSize etc etc..
addirittura ho riportato l'esempio su android http://developer.android.com/training/displaying-bitmaps/load-bitmap.html nel mio codice per calcolarmi quanto deve essere il valore inSimpleSize..
Insomma ne ho provate un bel po ma senza alcun risultato.
Nel mio layout xml la mia imageView e VideoView sono in questo modo:
Codice (XML): [Seleziona]
<VideoView android:id="@+id/spinview_pickrock" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" android:layout_below="@+id/spin_patchtop"/>
       <ImageView android:id="@+id/spin_covervideo" android:layout_width="wrap_content" android:layout_height="wrap_content"  android:background="@drawable/bgvideobetween" android:visibility="gone" android:layout_below="@+id/spin_patchtop"/>
Avete qualche idea? Grazie