Animation Drawable causing OutOfMemoryError on second run in Android

前端 未结 5 1078
傲寒
傲寒 2020-12-05 11:57

I am currently developing a game and I\'m trying to use one AnimationDrawable to show one animation in my Main Menu. When I run the game once, it works perfectly. But if i t

相关标签:
5条回答
  • 2020-12-05 12:27

    You need to free memory used by bitmaps, when you're exiting this screen. Unfortunately, for earlier versions of Android (afaik this was "fixed" since 3.0, but I can be wrong) memory for bitmaps is allocated through native code and, what is sad, memory should be freed explicitly.

    So, I suppose you to try this approach:

    1. Move code for AnimationDrawable to onResume() method.
    2. Add following code for releasing memory to onPause().

      ad.stop();
      for (int i = 0; i < ad.getNumberOfFrames(); ++i){
          Drawable frame = ad.getFrame(i);
          if (frame instanceof BitmapDrawable) {
              ((BitmapDrawable)frame).getBitmap().recycle();
          }
          frame.setCallback(null);
      }
      ad.setCallback(null);
      

    I hope it'll help you.

    0 讨论(0)
  • 2020-12-05 12:29

    So, I manage to solve my problem with this approach:

    Created one AsyncTask for drawing

    private class DrawRabbit extends AsyncTask<Void, Integer, Void> {    
         private int fps = 24;
         private int frame = 10014;
         private String drawableName; 
         @Override
           protected Void doInBackground(Void... params) {
             while (running){
               try {  
                if (frame == 10014)
                  Thread.sleep(1000);
                else 
                  Thread.sleep(fps);
              if (frame < 10160) { 
                frame++;
                publishProgress(frame);
              }
              else 
                running = false;
    
            } catch (InterruptedException e) { 
              e.printStackTrace();
            }
             }           
             return null;
           }
    
           protected void onProgressUpdate(Integer... frame) {
             drawableName = "rm" + frame[0];
             int res_id = getResources().getIdentifier(drawableName, "drawable", getPackageName());        
               rabbitFrame.setBackgroundResource(res_id);
           }   
       }
    

    and start it onWindowsFocusChanged

    public void onWindowFocusChanged(boolean hasFocus) {    
        super.onWindowFocusChanged(hasFocus);         
        if (hasFocus)
          new DrawRabbit().execute((Void)null) ;
        else 
          running = false;
        Log.d(TAG,"onFocusChanged");
      }
    

    Hope it helps someone!

    0 讨论(0)
  • 2020-12-05 12:33

    add these two lines in your android manifest file android:hardwareAccelerated="true" and android:largeHeap="true"

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.xxx.yyy" >
        <application
            android:allowBackup="false"
            android:fullBackupContent="false"
            android:hardwareAccelerated="true"
            android:largeHeap="true">
    </application>
    

    Hope that will help you.

    0 讨论(0)
  • 2020-12-05 12:37

    just add "android:largeHeap="true"" in application tag android manifest! :)

    0 讨论(0)
  • 2020-12-05 12:53

    You can try by reducing the size if images. My case it worked.

    int[] frames = {R.drawable.frame1, R.drawable.frame2, R.drawable.frame3};
    AnimationDrawable drawable = new AnimationDrawable();
        for (int fr : frames) {
            Bitmap sample = BitmapFactory.decodeResource(mActivity.getResources(), fr);
            sample = Bitmap.createScaledBitmap(sample, sample.getWidth()/4, sample.getHeight()/4, false);
            drawable.addFrame(new BitmapDrawable(mActivity.getResources(), sample), 30);
        }
    
    0 讨论(0)
提交回复
热议问题