Reputation: 1540
I have a layout with 2 buttons that each activates animation. On button click the layout with buttons disappearing and the animation starts. It works except one problem, I can`t activate the second animation after the first because memory problem. After one of the animations is played i have to somehow free memory so the second animation could load. How can I free the animation and delete all frames?
Here is my code:
public class BermadMain extends Activity {
public static final String TAG = "Bermad";
AnimationDrawable animation, animation2, animation3;
ImageView imageAnim;
RelativeLayout lay;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lay = (RelativeLayout) findViewById(R.id.rallay);
imageAnim = (ImageView) findViewById(R.id.imageView1);
final Button refinery = (Button) findViewById(R.id.refinery);
refinery.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int i=85;
animation = new AnimationDrawable();
animation.addFrame(getResources().getDrawable(R.drawable.ref1), i);
animation.addFrame(getResources().getDrawable(R.drawable.ref2), i);
animation.addFrame(getResources().getDrawable(R.drawable.ref3), i);
animation.addFrame(getResources().getDrawable(R.drawable.ref4), i);
animation.addFrame(getResources().getDrawable(R.drawable.ref5), i);
animation.addFrame(getResources().getDrawable(R.drawable.ref6), i);
animation.addFrame(getResources().getDrawable(R.drawable.ref7), i);
animation.addFrame(getResources().getDrawable(R.drawable.ref8), i);
animation.addFrame(getResources().getDrawable(R.drawable.ref9), i);
animation.addFrame(getResources().getDrawable(R.drawable.ref10), i);
animation.addFrame(getResources().getDrawable(R.drawable.ref11), i);
animation.addFrame(getResources().getDrawable(R.drawable.ref12), i);
animation.addFrame(getResources().getDrawable(R.drawable.ref13), i);
imageAnim.setBackgroundDrawable(animation);
imageAnim.post(new Refiney());
lay.setVisibility(View.GONE);
}
});
final Button oil = (Button) findViewById(R.id.oil);
oil.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int i=85;
animation2 = new AnimationDrawable();
animation2.addFrame(getResources().getDrawable(R.drawable.oil1), i);
animation2.addFrame(getResources().getDrawable(R.drawable.oil2), i);
animation2.addFrame(getResources().getDrawable(R.drawable.oil3), i);
animation2.addFrame(getResources().getDrawable(R.drawable.oil4), i);
animation2.addFrame(getResources().getDrawable(R.drawable.oil5), i);
animation2.addFrame(getResources().getDrawable(R.drawable.oil6), i);
animation2.addFrame(getResources().getDrawable(R.drawable.oil7), i);
animation2.addFrame(getResources().getDrawable(R.drawable.oil8), i);
animation2.addFrame(getResources().getDrawable(R.drawable.oil9), i);
animation2.addFrame(getResources().getDrawable(R.drawable.oil10), i);
animation2.addFrame(getResources().getDrawable(R.drawable.oil11), i);
animation2.addFrame(getResources().getDrawable(R.drawable.oil12), i);
animation2.addFrame(getResources().getDrawable(R.drawable.oil13), i);
imageAnim.setBackgroundDrawable(animation2);
imageAnim.post(new Oil());
lay.setVisibility(View.GONE);
}
});
}
public void onBackPressed() {
lay.setVisibility(View.VISIBLE);
return;
}
class Refiney implements Runnable {
public void run() {
animation.start();
}
}
class Oil implements Runnable {
public void run() {
animation2.start();
}
}
}
Upvotes: 0
Views: 4061
Reputation: 765
The problem with the AnimationDrawable is it will load all images to animationdrawable Object which became heavy while there where more than 12MB images. If you put largeHeap=true
it will adjust HeapSize and increase Heap that help to load more than 12MB but it will OutOfmemory while you have more bitmaps to load. For that scenario is
Use Handler
and runnable
for displaying image sequence one by one. That will load one by one image frame and not taking much memory.
Put your images file name with incremental number sequence and use below code for display it.
int i=0;
Runnable mRunnable = new Runnable() {
public void run() {
displayBitmap(i);
i++;
imageView.postDelayed(r, 0);
}
};
private void displayBitmap(int id) {
String filePath ="FullpathofFileName"+.jpg";
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap b = BitmapFactory.decodeFile(filePath, options);
if (b != null) {
imageView.setImageBitmap(b);
}
}
Upvotes: 0
Reputation: 71
I think you could try free your drawable loaded in animation. Check the unbindDrawables() method mentioned by Romain Guy's post. http://www.curious-creature.org/2008/12/18/avoid-memory-leaks-on-android/ (the code is not in the same git but you can google it other place). Then you can do System.gc() to reclaim memory.
I am not sure whether R.drawable.xxxx is preloaded in Android. If it is, then you shall not put the pictures in drawable but in resource, and dynamically load the bitmaps.
Animation itself is memory intense action. I have an animation causing a >3M byte array allocation in my app. Although the memory is reclaimed as soon as the animation finishes, it increases my peak memory usage and sometime leads to OutOfMemory.
Upvotes: 1
Reputation: 617
try to add largeHeap=true in your application tag of your manifest to know if it's only a memory problem.
Upvotes: 0