Play big animation PNG frame in android with animation

I have an application with buttons that play various frame animations when clicked. Animations are stored as sequences of .png files. Some of the animations fill a small area, and they seem to play beautifully with the animation. However, some of the animations fill most of the screen (although they are mostly transparent using the alpha channel), and I get an error from memory when the application loads on my phone (but not in the emulator). I cannot play them as video files, because they must overlap the main screen.

My main question is is there a way to play large animations of png sequences (say 60 frames at 320x480) using animation?

Until now, my research has in no way had memory limits ... so I studied my own method, which creates an ImageView and populates it with a bitmap, and then successively replaces the bitmap with each frame after a delay. However, with this technique, my animation seems to play only the first and last frames.

Here is the code for my hit when using animationDrawable - the chimpanzee plays fine, but when I add bubbles (large images), the application does not load at all - logCat shows: "ERROR / dalvikvm-heap (3248): external allocation of 1008,000 bytes too great for this process ... ERROR / AndroidRuntime (3248): java.lang.OutOfMemoryError: the size of the bitmap exceeds the VM budget "

public class Babymode_tst extends Activity implements OnClickListener{ /** Called when the activity is first created. */ AnimationDrawable chimpAnimation; AnimationDrawable bubblesAnimation; private MediaPlayer mp; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); setVolumeControlStream(AudioManager.STREAM_MUSIC); final ImageButton chimpButton = (ImageButton) findViewById(R.id.chimp_button); chimpButton.setOnClickListener(this); ImageView chimpImage = (ImageView) findViewById(R.id.chimp_imageview); chimpImage.setBackgroundResource(R.drawable.chimp_anim); chimpAnimation = (AnimationDrawable) chimpImage.getBackground(); final ImageButton bubblesButton = (ImageButton) findViewById(R.id.bubbles_button); bubblesButton.setOnClickListener(this); ImageView bubblesImage = (ImageView) findViewById(R.id.bubbles_imageview); bubblesImage.setBackgroundResource(R.drawable.bubbles_anim); bubblesAnimation = (AnimationDrawable) bubblesImage.getBackground(); } public void onClick(View v) { if (mp != null) { mp.release(); } Random generator = new Random(); int randomIndex; switch(v.getId()){ case R.id.chimp_button: randomIndex = (generator.nextInt( 2 ) + 1); if (randomIndex == 1){ mp = MediaPlayer.create(this, R.raw.chimp_1); } if (randomIndex == 2){ mp = MediaPlayer.create(this, R.raw.chimp_2); } mp.start(); chimpAnimation.setVisible(true,true); chimpAnimation.start(); break; case R.id.bubbles_button: randomIndex = (generator.nextInt( 3 ) + 1); if (randomIndex == 1){ mp = MediaPlayer.create(this, R.raw.bubbles_1); } if (randomIndex == 2){ mp = MediaPlayer.create(this, R.raw.bubbles_2); } if (randomIndex == 3){ mp = MediaPlayer.create(this, R.raw.bubbles_3); } mp.start(); bubblesAnimation.setVisible(true,true); bubblesAnimation.start(); break; } } } 

And here is my attempt to play frames one by one in ImageView, but it only plays the first and last frames:

  public void playAnimation(String name){ final ImageView bubblesImageView = (ImageView) findViewById(R.id.bubbles_imageview); bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0003); mHandler.postDelayed(new Runnable() { public void run() { bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0015); } }, 500); mHandler.postDelayed(new Runnable() { public void run() { bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0025); } }, 500); mHandler.postDelayed(new Runnable() { public void run() { bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0035); } }, 500); } 

Any help would be appreciated - thanks

+4
source share
3 answers

your mHandler.postDelayed(new Runnable(){...}); everything starts simultaneously, for example. after 500 ms you need them to start one by one with

 nHandler.postDelayed(new Runnable() { public void run() { bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0015); } }, 500); mHandler.postDelayed(new Runnable() { public void run() { bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0025); } }, 1000); mHandler.postDelayed(new Runnable() { public void run() { bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0035); } }, 1500); 

or with each running queue of the next after a delay of 500 ms, for example.

 mHandler.postDelayed(new Runnable() { public void run() { bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0015); mHandler.postDelayed(new Runnable() { public void run() { bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0025); } }, 1000); } }, 500); 

Or you could build an Γ¬nt array with the value R.drawable.xxx , and every 500 ms just display the following image.

+1
source

In my company, we faced the same problem, so we tried to make a splash screen this way (and it was a complete disaster). If it’s so hard for you to get some kind of animation, generate the video from PNG frames (I think FFMPEG can do this), and then play the video.

0
source

This is a very difficult task, but it is doable. The key is to recycle your bitmaps immediately after using them. Check out this shell class that someone wrote that will handle all this for you: http://snippetrepo.com/snippets/android-animation-without-outofmemoryerror

0
source

Source: https://habr.com/ru/post/1333544/


All Articles