Android - Unable to figure out memory leak in a lockscreen type application -
i have feeling problem quite similar this, not same.
i have application activity loads image upon receiving event. user swipes on image, , activity finishes. next time user switches off screen , switches on, same event triggers, , activity loads again.
this works fine, every time activity loads, increases memory (4mb 8mb 11mb 14mb etc.). goes around 30mb , either application crashes & restarts or phone starts getting sluggish etc.
i have tried number of things: - clearing & setting image related variables & view after utilize - using reusebitmap
but hasn't helped.
can suggests missing?
also, finish() doesn't seem finishing activity. keeping in background. if long press home, can see activity there, don't want happen. there way prepare that? cause of problem?
my start-up activity (which runs once), kicks off service:
protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_settings); startservice(new intent(this.getapplicationcontext(),myservice.class)); }
my service kicks off event broadcaster:
public void oncreate() { keyguardmanager.keyguardlock k1; keyguardmanager km =(keyguardmanager)getsystemservice(keyguard_service); k1= km.newkeyguardlock("in"); k1.disablekeyguard(); log.i("event", "servicestarted"); intentfilter filter = new intentfilter(intent.action_screen_on); filter.addaction(intent.action_screen_off); mreceiver = new eventsreciever(); registerreceiver (mreceiver, filter); super.oncreate(); }
when event occurs, kicks off main activity:
public void onreceive(context context, intent recievedintent) { log.i("check","[broadcastreciever] onrecieve()"); if (recievedintent.getaction().equals(intent.action_screen_off)) { wasscreenon = false; log.i("check","[broadcastreciever] screen went off"); intent intent11 = new intent(context,mainactivity.class); intent11.addflags(intent.flag_activity_new_task); context.startactivity(intent11); } else if (recievedintent.getaction().equals(intent.action_screen_on)) { wasscreenon = true; log.i("check","[broadcastreciever] screen went on"); intent intent11 = new intent(context, mainactivity.class); intent11.addflags(intent.flag_activity_new_task); } else if(recievedintent.getaction().equals(intent.action_boot_completed)) { intent intent11 = new intent(context, mainactivity.class); intent11.addflags(intent.flag_activity_new_task); context.startactivity(intent11); } } }
and here little more complex activity code. sense issue might somewhere here, unable figure out:
public class mainactivity extends activity { private static bitmap reusedbitmap; @override protected void oncreate(bundle savedinstancestate) { log.i("event", "activity oncreate"); requestwindowfeature(window.feature_no_title); this.getwindow().settype(windowmanager.layoutparams.type_keyguard_dialog); super.oncreate(savedinstancestate); getwindow().addflags(windowmanager.layoutparams.flag_keep_screen_on|windowmanager.layoutparams.flag_show_when_locked|windowmanager.layoutparams.flag_fullscreen); setcontentview(r.layout.activity_main); if (getintent()!=null&&getintent().hasextra("kill")&&getintent().getextras().getint("kill")==1){ // toast.maketext(this, "" + "kill activity", toast.length_short).show(); finish(); } try{ settime(); imageview img2 = (imageview)findviewbyid(r.id.imageview); changeimage(false); img2.setontouchlistener(new onswipetouchlistener(this) { @override public void onswipeleft() { changeimage(true); log.i("event","onswipeleft"); } @override public void onswiperight() { textview tvdisplaydate = (textview)findviewbyid(r.id.date1); customdigitalclock cdc = (customdigitalclock)findviewbyid(r.id.dc1); if (tvdisplaydate.getvisibility()==view.visible) { tvdisplaydate.setvisibility(view.gone); cdc.setvisibility(view.gone); } else { tvdisplaydate.setvisibility(view.visible); cdc.setvisibility(view.visible); } } @override public void onswipeup() { // mainactivity.this.movetasktoback(true); vcounter = 0; reusedbitmap = null; finish(); } @override public void onswipedown() { } }); img2.destroydrawingcache(); img2 = null; } grab (exception e) { } } public void settime() { textview tvdisplaydate = (textview)findviewbyid(r.id.date1); final calendar c = calendar.getinstance(); int yy = c.get(calendar.year); int mm = c.get(calendar.month); int dd = c.get(calendar.day_of_month); simpledateformat dayformat = new simpledateformat("e", locale.getdefault()); string weekday = dayformat.format(c.gettime());; // set current date textview tvdisplaydate.settext(new stringbuilder() // month 0 based, add together 1 .append(yy).append(" ").append("-").append(" ").append(mm + 1).append(" ") .append("-").append(dd).append(" ").append(weekday)); } @override public void onbackpressed() { // don't allow dismiss. return; } //only used in lockdown mode @override protected void onpause() { super.onpause(); log.i("event","onpause"); } @override protected void onresume() { super.onresume(); log.i("event", "onresume"); } @override protected void onstart() { log.i("event", "activity onstart"); super.onstart(); } @override protected void onstop() { log.i("event","onstop"); reusedbitmap = null; } @override public boolean onkeydown(int keycode, keyevent event) { log.i("event", "key pressed " + keycode); if ((keycode == keyevent.keycode_volume_down)||(keycode == keyevent.keycode_power)||(keycode == keyevent.keycode_volume_up)||(keycode == keyevent.keycode_camera)) { homecoming true; //because handled event } if((keycode == keyevent.keycode_home)){ toast.maketext(this, "you pressed home button", toast.length_long).show(); homecoming true; } if ( keycode == keyevent.keycode_menu ) { // nil homecoming true; } homecoming false; } public void ondestroy(){ super.ondestroy(); } public boolean dispatchkeyevent(keyevent event) { if (event.getkeycode() == keyevent.keycode_power ||(event.getkeycode() == keyevent.keycode_volume_down)||(event.getkeycode() == keyevent.keycode_power)) { homecoming false; } if((event.getkeycode() == keyevent.keycode_home)){ system.out.println("home key press event sent"); homecoming true; } homecoming false; } public void changeimage(boolean vforce) { string pathv = null; sharedpreferences pref = getapplicationcontext().getsharedpreferences("mypref", 0); // 0 - private mode boolean vpicchosen; vpicchosen = pref.getboolean("picchosen", false); if (vpicchosen == true) { pathv = pref.getstring("picurl", "nopic"); } else pathv = "nopic"; if (pathv == "nopic" || vforce == true) { pathv = randompic(); } file imgfile = new file(pathv); if(imgfile.exists()) { imageview img1 = (imageview)findviewbyid(r.id.imageview); display display = getwindowmanager().getdefaultdisplay(); int width = display.getwidth(); int height = display.getheight(); bitmap bmp2 = decodesampledbitmapfrompath(pathv, width, height); img1.destroydrawingcache(); img1.setimagebitmap(bmp2); img1.destroydrawingcache(); bmp2 = null; img1 = null; imgfile = null; } else toast.maketext(this, "no image present", toast.length_short).show(); } public static bitmap decodesampledbitmapfrompath(string path, int reqwidth, int reqheight) { // first decode injustdecodebounds=true check dimensions final bitmapfactory.options options = new bitmapfactory.options(); options.injustdecodebounds = true; options.inbitmap = reusedbitmap; bitmapfactory.decodefile(path, options); // calculate insamplesize options.insamplesize = calculateinsamplesize(options, reqwidth, reqheight); // decode bitmap insamplesize set options.injustdecodebounds = false; homecoming bitmapfactory.decodefile(path, options); } public class onswipetouchlistener implements ontouchlistener { private final gesturedetector gesturedetector; public onswipetouchlistener(context context) { gesturedetector = new gesturedetector(context, new gesturelistener()); } public void onswipeleft() { } public void onswiperight() { } public void onswipeup() { } public void onswipedown() { } public boolean ontouch(view v, motionevent event) { homecoming gesturedetector.ontouchevent(event); } private final class gesturelistener extends simpleongesturelistener { private static final int swipe_distance_threshold = 100; private static final int swipe_velocity_threshold = 100; @override public boolean ondown(motionevent e) { homecoming true; } @override public boolean onfling(motionevent e1, motionevent e2, float velocityx, float velocityy) { float distancex = e2.getx() - e1.getx(); float distancey = e2.gety() - e1.gety(); if (math.abs(distancex) > math.abs(distancey) && math.abs(distancex) > swipe_distance_threshold && math.abs(velocityx) > swipe_velocity_threshold) { if (distancex > 0) onswiperight(); else onswipeleft(); homecoming true; } if (math.abs(distancey) > math.abs(distancex) && math.abs(distancey) > swipe_distance_threshold && math.abs(velocityy) > swipe_velocity_threshold) { if (distancey < 0) onswipeup(); else onswipedown(); homecoming true; } homecoming false; } } } public string randompic(){ file dir = new file(path4); file childfile[] = dir.listfiles(); integer numfiles = childfile.length; random r1=new random(); integer selfile = r1.nextint(numfiles); sharedpreferences pref = getapplicationcontext().getsharedpreferences("mypref", 0); // 0 - private mode editor editor = pref.edit(); editor.putboolean("picchosen", true); editor.putstring("picurl", childfile[selfile].getpath()); editor.commit(); dir = null; homecoming childfile[selfile].getpath(); } }
any clues on might missing please?
edit 1:
this line seems causing problem:
bitmap bmp2 = decodesampledbitmapfrompath(pathv, width, height);
i changed below, reuse static bitmap variable:
// reusedbitmap.recycle(); reusedbitmap = decodesampledbitmapfrompath(pathv, width, height);
if recycle variable before reusing (as suggested gabe), image not loading @ all, stranger.
edit 2:
if seek recycle reusedbitmap within changeimage method, imageview isn't loading image @ all. , if recycle reusedbitmap within onswipeup (just before finish), not creating positive effect. memory consumption remaining same in case.
android android-intent memory-leaks android-event android-bitmap
No comments:
Post a Comment