So, I have a quite simple test project. A timer that every even iteration spawns a view and every odd iteration kills the view. The view itself is a RelativeLayout with an image. What I want to do is to be able to let this time run indefinitely without havig memory issues. Thing is, I don't know how to truly clear the image stream I use to create the bitmap out of the memory. I am recycling the bitmap when I don't need it anymore but that's not enough. The code is in C# (Xamarin), but java answers also help.
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
RelativeLayout mainView = new RelativeLayout (this);
this.AddContentView(mainView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent));
...
int i = 0;
System.Timers.Timer t = new System.Timers.Timer (100);
t.Elapsed += delegate(object sender, System.Timers.ElapsedEventArgs e) {
RunOnUiThread(delegate() {
if(i++ % 2 == 0){
tmpView tView = new tmpView(this);
mainView.AddView(tView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent));
}else{
((tmpView)mainView.GetChildAt(0)).dispose();
mainView.RemoveAllViews();
}
});
};
t.AutoReset = true;
t.Start ();
}
private class tmpView:RelativeLayout{
ImageView img;
Android.Graphics.Bitmap bmp;
public tmpView(Context cntx):base(cntx){
SetBackgroundColor(new Android.Graphics.Color(200, 0, 0, 200));
System.IO.Stream imgStream = Application.Context.Assets.Open ("backgroundLeft.png");
img = new ImageView(cntx);
bmp = Android.Graphics.BitmapFactory.DecodeStream (imgStream);
img.SetImageBitmap(bmp);
//bmp.Recycle();
imgStream.Close();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MatchParent, 500);
lp.TopMargin = 150;
this.AddView(img, lp);
}
public void dispose(){
bmp.Recycle ();
img.SetImageDrawable (null);
}
}
Also, the reason why I say that the image stream is what's causing the memory leaks is because I'm actually able to make this time run the whole day. I have to add GC calls right after the imgStream.Close();
( GC.SuppressFinalize(imgStream);
and GC.Collect();
). But calling the GC will cause noticeable lag, and besides, I dont want to wipe everything, just the stream. Also, this is running on a device.
Ty, Axel
I'd recommend you check this small talk about memory on Android:
https://realm.io/news/droidcon-ricau-memory-leaks-leakcanary/
It's pretty interesting, and should explain why your image is retained in a context not cleaned by the garbage collector.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.