[android-developers] Re: Memory Leak when creating OnClickListener
Still struggling with this, anyone have any ideas? - Dan On Sun, Aug 16, 2009 at 12:07 AM, Dan Sherman impact...@gmail.com wrote: After some more testing, it doesn't look like it has anything to do with creating a new OnClickListener each time. The following snippet (using the same Layouts), produces the same leak. Its significantly shorter, and when looking at a heap dump, from what I can tell, an array called mActions in ViewRoot is filling with Runnables (presumably these callbacks), but I'm no expert (and have very little experience in heap dump analysis). public class SetContentTest extends Activity implements OnClickListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setMode(); } @Override public void onClick(View v) { setMode(); } public void setMode() { setContentView(R.layout.main); ((Button) findViewById(R.id.btn_main)).setOnClickListener(this); } } Anyone have any ideas? - Dan On Sat, Aug 15, 2009 at 11:56 PM, Balwinder Kaur (T-Mobile USA) balwinder.k...@t-mobile.com wrote: I'm curious too, but seriously you should go with the other options you mentioned. Creating new onClickListeners with each click is NOT a good idea ! Balwinder Kaur Open Source Development Center ·T· · ·Mobile· stick together The views, opinions and statements in this email are those of the author solely in their individual capacity, and do not necessarily represent those of T-Mobile USA, Inc. On Aug 15, 7:25 pm, Dan Sherman impact...@gmail.com wrote: Hey guys, Was curious if anyone could point our a way to avoid the following memory leak. When switching layouts in a single activity, and assigning OnClickListeners to buttons, each assignment looks to leak a bit of memory. Below is a quick example application that shows it happening with two Button's and a simple function to switch which layout is currently active. If run, you'll see the used memory jump slightly with each click between them. I'm aware there's plenty of ways around it (using multiple activities for each layout, using a single OnClickListener thats a member variable which gets assigned to it each time), just curious as to where that extra reference is going thats not getting collected. public class SetContentTest extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btn = (Button) findViewById(R.id.btn_main); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(false); } }); } public void setMode(boolean main) { if (main) { setContentView(R.layout.main); Button btn = (Button) findViewById(R.id.btn_main); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(false); } }); } else { setContentView(R.layout.other); Button btn = (Button) findViewById(R.id.btn_other); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(true); } }); } } } And the layouts: ?xml version=1.0 encoding=utf-8? LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation=vertical android:layout_width=fill_parent android:layout_height=fill_parent Button android:id=@+id/btn_main android:layout_width=wrap_content android:layout_height=wrap_content android:text=Click for Other / /LinearLayout -- ?xml version=1.0 encoding=utf-8? LinearLayout xmlns:android=http://schemas.android.com/apk/res/android android:orientation=vertical android:layout_width=fill_parent android:layout_height=fill_parent Button android:id=@+id/btn_other android:layout_width=wrap_content android:layout_height=wrap_content android:text=Click for Main / /LinearLayout Only difference between the layouts is the name (btn_main and btn_other) - Dan --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at
[android-developers] Re: Memory Leak when creating OnClickListener
What is the type of the object in the array that is increasing in number? On Mon, Aug 17, 2009 at 9:36 AM, Dan Sherman impact...@gmail.com wrote: Still struggling with this, anyone have any ideas? - Dan On Sun, Aug 16, 2009 at 12:07 AM, Dan Sherman impact...@gmail.com wrote: After some more testing, it doesn't look like it has anything to do with creating a new OnClickListener each time. The following snippet (using the same Layouts), produces the same leak. Its significantly shorter, and when looking at a heap dump, from what I can tell, an array called mActions in ViewRoot is filling with Runnables (presumably these callbacks), but I'm no expert (and have very little experience in heap dump analysis). public class SetContentTest extends Activity implements OnClickListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setMode(); } @Override public void onClick(View v) { setMode(); } public void setMode() { setContentView(R.layout.main); ((Button) findViewById(R.id.btn_main)).setOnClickListener(this); } } Anyone have any ideas? - Dan On Sat, Aug 15, 2009 at 11:56 PM, Balwinder Kaur (T-Mobile USA) balwinder.k...@t-mobile.com wrote: I'm curious too, but seriously you should go with the other options you mentioned. Creating new onClickListeners with each click is NOT a good idea ! Balwinder Kaur Open Source Development Center ·T· · ·Mobile· stick together The views, opinions and statements in this email are those of the author solely in their individual capacity, and do not necessarily represent those of T-Mobile USA, Inc. On Aug 15, 7:25 pm, Dan Sherman impact...@gmail.com wrote: Hey guys, Was curious if anyone could point our a way to avoid the following memory leak. When switching layouts in a single activity, and assigning OnClickListeners to buttons, each assignment looks to leak a bit of memory. Below is a quick example application that shows it happening with two Button's and a simple function to switch which layout is currently active. If run, you'll see the used memory jump slightly with each click between them. I'm aware there's plenty of ways around it (using multiple activities for each layout, using a single OnClickListener thats a member variable which gets assigned to it each time), just curious as to where that extra reference is going thats not getting collected. public class SetContentTest extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btn = (Button) findViewById(R.id.btn_main); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(false); } }); } public void setMode(boolean main) { if (main) { setContentView(R.layout.main); Button btn = (Button) findViewById(R.id.btn_main); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(false); } }); } else { setContentView(R.layout.other); Button btn = (Button) findViewById(R.id.btn_other); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(true); } }); } } } And the layouts: ?xml version=1.0 encoding=utf-8? LinearLayout xmlns:android= http://schemas.android.com/apk/res/android; android:orientation=vertical android:layout_width=fill_parent android:layout_height=fill_parent Button android:id=@+id/btn_main android:layout_width=wrap_content android:layout_height=wrap_content android:text=Click for Other / /LinearLayout -- ?xml version=1.0 encoding=utf-8? LinearLayout xmlns:android= http://schemas.android.com/apk/res/android; android:orientation=vertical android:layout_width=fill_parent android:layout_height=fill_parent Button android:id=@+id/btn_other android:layout_width=wrap_content android:layout_height=wrap_content android:text=Click for Main / /LinearLayout Only difference between the layouts is the name (btn_main and btn_other) - Dan -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails. All such
[android-developers] Re: Memory Leak when creating OnClickListener
Looks to be a Runnable (from what I can tell). On Mon, Aug 17, 2009 at 12:49 PM, Dianne Hackborn hack...@android.comwrote: What is the type of the object in the array that is increasing in number? On Mon, Aug 17, 2009 at 9:36 AM, Dan Sherman impact...@gmail.com wrote: Still struggling with this, anyone have any ideas? - Dan On Sun, Aug 16, 2009 at 12:07 AM, Dan Sherman impact...@gmail.comwrote: After some more testing, it doesn't look like it has anything to do with creating a new OnClickListener each time. The following snippet (using the same Layouts), produces the same leak. Its significantly shorter, and when looking at a heap dump, from what I can tell, an array called mActions in ViewRoot is filling with Runnables (presumably these callbacks), but I'm no expert (and have very little experience in heap dump analysis). public class SetContentTest extends Activity implements OnClickListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setMode(); } @Override public void onClick(View v) { setMode(); } public void setMode() { setContentView(R.layout.main); ((Button) findViewById(R.id.btn_main)).setOnClickListener(this); } } Anyone have any ideas? - Dan On Sat, Aug 15, 2009 at 11:56 PM, Balwinder Kaur (T-Mobile USA) balwinder.k...@t-mobile.com wrote: I'm curious too, but seriously you should go with the other options you mentioned. Creating new onClickListeners with each click is NOT a good idea ! Balwinder Kaur Open Source Development Center ·T· · ·Mobile· stick together The views, opinions and statements in this email are those of the author solely in their individual capacity, and do not necessarily represent those of T-Mobile USA, Inc. On Aug 15, 7:25 pm, Dan Sherman impact...@gmail.com wrote: Hey guys, Was curious if anyone could point our a way to avoid the following memory leak. When switching layouts in a single activity, and assigning OnClickListeners to buttons, each assignment looks to leak a bit of memory. Below is a quick example application that shows it happening with two Button's and a simple function to switch which layout is currently active. If run, you'll see the used memory jump slightly with each click between them. I'm aware there's plenty of ways around it (using multiple activities for each layout, using a single OnClickListener thats a member variable which gets assigned to it each time), just curious as to where that extra reference is going thats not getting collected. public class SetContentTest extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btn = (Button) findViewById(R.id.btn_main); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(false); } }); } public void setMode(boolean main) { if (main) { setContentView(R.layout.main); Button btn = (Button) findViewById(R.id.btn_main); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(false); } }); } else { setContentView(R.layout.other); Button btn = (Button) findViewById(R.id.btn_other); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(true); } }); } } } And the layouts: ?xml version=1.0 encoding=utf-8? LinearLayout xmlns:android= http://schemas.android.com/apk/res/android; android:orientation=vertical android:layout_width=fill_parent android:layout_height=fill_parent Button android:id=@+id/btn_main android:layout_width=wrap_content android:layout_height=wrap_content android:text=Click for Other / /LinearLayout -- ?xml version=1.0 encoding=utf-8? LinearLayout xmlns:android= http://schemas.android.com/apk/res/android; android:orientation=vertical android:layout_width=fill_parent android:layout_height=fill_parent Button android:id=@+id/btn_other android:layout_width=wrap_content android:layout_height=wrap_content android:text=Click for Main / /LinearLayout Only difference between the layouts is the name (btn_main and btn_other) - Dan -- Dianne Hackborn Android framework engineer hack...@android.com Note: please
[android-developers] Re: Memory Leak when creating OnClickListener
On Mon, Aug 17, 2009 at 9:57 AM, Dan Sherman impact...@gmail.com wrote: Looks to be a Runnable (from what I can tell). It can't just be a Runnable, it needs to be a concrete implementation of Runnable. I am pretty sure hat will show you the actual class implementation, since it only deals in concrete classes. This may be an (anonymous) inner class, in which case there should be fields in it you can follow to get back to a more interesting class. -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails. All such questions should be posted on public forums, where I and others can see and answer them. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~--~~~~--~~--~--~---
[android-developers] Re: Memory Leak when creating OnClickListener
I'll check it out tonight when I get access to the dump again. But from what I remember, it was just a really long list of nested Runnables (I'm sure I missed something). Would it help if I posted the dump? - Dan On Mon, Aug 17, 2009 at 1:39 PM, Dianne Hackborn hack...@android.comwrote: On Mon, Aug 17, 2009 at 9:57 AM, Dan Sherman impact...@gmail.com wrote: Looks to be a Runnable (from what I can tell). It can't just be a Runnable, it needs to be a concrete implementation of Runnable. I am pretty sure hat will show you the actual class implementation, since it only deals in concrete classes. This may be an (anonymous) inner class, in which case there should be fields in it you can follow to get back to a more interesting class. -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails. All such questions should be posted on public forums, where I and others can see and answer them. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~--~~~~--~~--~--~---
[android-developers] Re: Memory Leak when creating OnClickListener
Please do. On Mon, Aug 17, 2009 at 10:45 AM, Dan Shermanimpact...@gmail.com wrote: I'll check it out tonight when I get access to the dump again. But from what I remember, it was just a really long list of nested Runnables (I'm sure I missed something). Would it help if I posted the dump? - Dan On Mon, Aug 17, 2009 at 1:39 PM, Dianne Hackborn hack...@android.com wrote: On Mon, Aug 17, 2009 at 9:57 AM, Dan Sherman impact...@gmail.com wrote: Looks to be a Runnable (from what I can tell). It can't just be a Runnable, it needs to be a concrete implementation of Runnable. I am pretty sure hat will show you the actual class implementation, since it only deals in concrete classes. This may be an (anonymous) inner class, in which case there should be fields in it you can follow to get back to a more interesting class. -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails. All such questions should be posted on public forums, where I and others can see and answer them. -- Romain Guy Android framework engineer romain...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~--~~~~--~~--~--~---
[android-developers] Re: Memory Leak when creating OnClickListener
You are indeed causing a leak in a nasty way. What's going on is the following: - The button is attached to a window - You press the button - The button executes the click listener - In the click listener you setContentView() - This in turns detaches the button from the window - The button finishes handling the click and tries to unset its pressed state by calling View.post(Runnable) - There's no window, so the Runnable is enqueued in ViewRoot - The runnable queue is never looked at because the first layout already happened To fix it's simple: @Override public void onClick(View v) { v.post(new Runnable() { public void run() { setMode(); } }): } I'll add a fix in Eclair for this but really you should consider what you're doing. Changing the content view is not really how Android apps usually work, instead you should use a different activity. On Mon, Aug 17, 2009 at 6:26 PM, Dan Shermanimpact...@gmail.com wrote: Dump is attached. Shows the application state after about 50 clicks on the button. Again, sorry for my ineptitude in the dump analysis, just haven't worked with them enough. Looks to be that mActions (ArrayList) is growing with lots of android.view.ViewRoot$ RunQueue$HandlerAction (which I imagine is a callback that gets setup with the OnClickListener). The code used to create is as follows: public class SetContentTest extends Activity implements OnClickListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setMode(); } @Override public void onClick(View v) { setMode(); } public void setMode() { setContentView(R.layout.main); ((Button) findViewById(R.id.btn_main)).setOnClickListener(this); } } Thanks again :) On Mon, Aug 17, 2009 at 9:21 PM, Dan Sherman impact...@gmail.com wrote: Dumps are attached. One pre-leak (start of application), and one after about 50ish clicks on the button, which causes the leak. Again, sorry for my ineptitude in the dump analysis, just haven't worked with them enough. Looks to be that mActions (ArrayList) is growing with lots of android.view.ViewRoot$RunQueue$HandlerAction (which I imagine is a callback that gets setup with the OnClickListener). The code used to create is as follows: public class SetContentTest extends Activity implements OnClickListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setMode(); } @Override public void onClick(View v) { setMode(); } public void setMode() { setContentView(R.layout.main); ((Button) findViewById(R.id.btn_main)).setOnClickListener(this); } } Thanks guys :) On Mon, Aug 17, 2009 at 2:11 PM, Romain Guy romain...@google.com wrote: Please do. On Mon, Aug 17, 2009 at 10:45 AM, Dan Shermanimpact...@gmail.com wrote: I'll check it out tonight when I get access to the dump again. But from what I remember, it was just a really long list of nested Runnables (I'm sure I missed something). Would it help if I posted the dump? - Dan On Mon, Aug 17, 2009 at 1:39 PM, Dianne Hackborn hack...@android.com wrote: On Mon, Aug 17, 2009 at 9:57 AM, Dan Sherman impact...@gmail.com wrote: Looks to be a Runnable (from what I can tell). It can't just be a Runnable, it needs to be a concrete implementation of Runnable. I am pretty sure hat will show you the actual class implementation, since it only deals in concrete classes. This may be an (anonymous) inner class, in which case there should be fields in it you can follow to get back to a more interesting class. -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails. All such questions should be posted on public forums, where I and others can see and answer them. -- Romain Guy Android framework engineer romain...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them -- Romain Guy Android framework engineer romain...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options,
[android-developers] Re: Memory Leak when creating OnClickListener
Thanks a ton :) I understand completely that this is a horrible use of setContentView(), and I imagined that was what the problem was, however, just wanted to make sure I wasn't losing my marbles here. Great job with Android so far, keep up the good work :) On Mon, Aug 17, 2009 at 11:14 PM, Romain Guy romain...@google.com wrote: You are indeed causing a leak in a nasty way. What's going on is the following: - The button is attached to a window - You press the button - The button executes the click listener - In the click listener you setContentView() - This in turns detaches the button from the window - The button finishes handling the click and tries to unset its pressed state by calling View.post(Runnable) - There's no window, so the Runnable is enqueued in ViewRoot - The runnable queue is never looked at because the first layout already happened To fix it's simple: @Override public void onClick(View v) { v.post(new Runnable() { public void run() { setMode(); } }): } I'll add a fix in Eclair for this but really you should consider what you're doing. Changing the content view is not really how Android apps usually work, instead you should use a different activity. On Mon, Aug 17, 2009 at 6:26 PM, Dan Shermanimpact...@gmail.com wrote: Dump is attached. Shows the application state after about 50 clicks on the button. Again, sorry for my ineptitude in the dump analysis, just haven't worked with them enough. Looks to be that mActions (ArrayList) is growing with lots of android.view.ViewRoot$ RunQueue$HandlerAction (which I imagine is a callback that gets setup with the OnClickListener). The code used to create is as follows: public class SetContentTest extends Activity implements OnClickListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setMode(); } @Override public void onClick(View v) { setMode(); } public void setMode() { setContentView(R.layout.main); ((Button) findViewById(R.id.btn_main)).setOnClickListener(this); } } Thanks again :) On Mon, Aug 17, 2009 at 9:21 PM, Dan Sherman impact...@gmail.com wrote: Dumps are attached. One pre-leak (start of application), and one after about 50ish clicks on the button, which causes the leak. Again, sorry for my ineptitude in the dump analysis, just haven't worked with them enough. Looks to be that mActions (ArrayList) is growing with lots of android.view.ViewRoot$RunQueue$HandlerAction (which I imagine is a callback that gets setup with the OnClickListener). The code used to create is as follows: public class SetContentTest extends Activity implements OnClickListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setMode(); } @Override public void onClick(View v) { setMode(); } public void setMode() { setContentView(R.layout.main); ((Button) findViewById(R.id.btn_main)).setOnClickListener(this); } } Thanks guys :) On Mon, Aug 17, 2009 at 2:11 PM, Romain Guy romain...@google.com wrote: Please do. On Mon, Aug 17, 2009 at 10:45 AM, Dan Shermanimpact...@gmail.com wrote: I'll check it out tonight when I get access to the dump again. But from what I remember, it was just a really long list of nested Runnables (I'm sure I missed something). Would it help if I posted the dump? - Dan On Mon, Aug 17, 2009 at 1:39 PM, Dianne Hackborn hack...@android.com wrote: On Mon, Aug 17, 2009 at 9:57 AM, Dan Sherman impact...@gmail.com wrote: Looks to be a Runnable (from what I can tell). It can't just be a Runnable, it needs to be a concrete implementation of Runnable. I am pretty sure hat will show you the actual class implementation, since it only deals in concrete classes. This may be an (anonymous) inner class, in which case there should be fields in it you can follow to get back to a more interesting class. -- Dianne Hackborn Android framework engineer hack...@android.com Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails. All such questions should be posted on public forums, where I and others can see and answer them. -- Romain Guy Android framework engineer romain...@android.com Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them -- Romain Guy Android framework engineer romain...@android.com Note: please don't send
[android-developers] Re: Memory Leak when creating OnClickListener
I'm curious too, but seriously you should go with the other options you mentioned. Creating new onClickListeners with each click is NOT a good idea ! Balwinder Kaur Open Source Development Center ·T· · ·Mobile· stick together The views, opinions and statements in this email are those of the author solely in their individual capacity, and do not necessarily represent those of T-Mobile USA, Inc. On Aug 15, 7:25 pm, Dan Sherman impact...@gmail.com wrote: Hey guys, Was curious if anyone could point our a way to avoid the following memory leak. When switching layouts in a single activity, and assigning OnClickListeners to buttons, each assignment looks to leak a bit of memory. Below is a quick example application that shows it happening with two Button's and a simple function to switch which layout is currently active. If run, you'll see the used memory jump slightly with each click between them. I'm aware there's plenty of ways around it (using multiple activities for each layout, using a single OnClickListener thats a member variable which gets assigned to it each time), just curious as to where that extra reference is going thats not getting collected. public class SetContentTest extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btn = (Button) findViewById(R.id.btn_main); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(false); } }); } public void setMode(boolean main) { if (main) { setContentView(R.layout.main); Button btn = (Button) findViewById(R.id.btn_main); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(false); } }); } else { setContentView(R.layout.other); Button btn = (Button) findViewById(R.id.btn_other); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(true); } }); } } } And the layouts: ?xml version=1.0 encoding=utf-8? LinearLayout xmlns:android=http://schemas.android.com/apk/res/android; android:orientation=vertical android:layout_width=fill_parent android:layout_height=fill_parent Button android:id=@+id/btn_main android:layout_width=wrap_content android:layout_height=wrap_content android:text=Click for Other / /LinearLayout -- ?xml version=1.0 encoding=utf-8? LinearLayout xmlns:android=http://schemas.android.com/apk/res/android; android:orientation=vertical android:layout_width=fill_parent android:layout_height=fill_parent Button android:id=@+id/btn_other android:layout_width=wrap_content android:layout_height=wrap_content android:text=Click for Main / /LinearLayout Only difference between the layouts is the name (btn_main and btn_other) - Dan --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~--~~~~--~~--~--~---
[android-developers] Re: Memory Leak when creating OnClickListener
After some more testing, it doesn't look like it has anything to do with creating a new OnClickListener each time. The following snippet (using the same Layouts), produces the same leak. Its significantly shorter, and when looking at a heap dump, from what I can tell, an array called mActions in ViewRoot is filling with Runnables (presumably these callbacks), but I'm no expert (and have very little experience in heap dump analysis). public class SetContentTest extends Activity implements OnClickListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setMode(); } @Override public void onClick(View v) { setMode(); } public void setMode() { setContentView(R.layout.main); ((Button) findViewById(R.id.btn_main)).setOnClickListener(this); } } Anyone have any ideas? - Dan On Sat, Aug 15, 2009 at 11:56 PM, Balwinder Kaur (T-Mobile USA) balwinder.k...@t-mobile.com wrote: I'm curious too, but seriously you should go with the other options you mentioned. Creating new onClickListeners with each click is NOT a good idea ! Balwinder Kaur Open Source Development Center ·T· · ·Mobile· stick together The views, opinions and statements in this email are those of the author solely in their individual capacity, and do not necessarily represent those of T-Mobile USA, Inc. On Aug 15, 7:25 pm, Dan Sherman impact...@gmail.com wrote: Hey guys, Was curious if anyone could point our a way to avoid the following memory leak. When switching layouts in a single activity, and assigning OnClickListeners to buttons, each assignment looks to leak a bit of memory. Below is a quick example application that shows it happening with two Button's and a simple function to switch which layout is currently active. If run, you'll see the used memory jump slightly with each click between them. I'm aware there's plenty of ways around it (using multiple activities for each layout, using a single OnClickListener thats a member variable which gets assigned to it each time), just curious as to where that extra reference is going thats not getting collected. public class SetContentTest extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btn = (Button) findViewById(R.id.btn_main); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(false); } }); } public void setMode(boolean main) { if (main) { setContentView(R.layout.main); Button btn = (Button) findViewById(R.id.btn_main); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(false); } }); } else { setContentView(R.layout.other); Button btn = (Button) findViewById(R.id.btn_other); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { setMode(true); } }); } } } And the layouts: ?xml version=1.0 encoding=utf-8? LinearLayout xmlns:android=http://schemas.android.com/apk/res/android; android:orientation=vertical android:layout_width=fill_parent android:layout_height=fill_parent Button android:id=@+id/btn_main android:layout_width=wrap_content android:layout_height=wrap_content android:text=Click for Other / /LinearLayout -- ?xml version=1.0 encoding=utf-8? LinearLayout xmlns:android=http://schemas.android.com/apk/res/android; android:orientation=vertical android:layout_width=fill_parent android:layout_height=fill_parent Button android:id=@+id/btn_other android:layout_width=wrap_content android:layout_height=wrap_content android:text=Click for Main / /LinearLayout Only difference between the layouts is the name (btn_main and btn_other) - Dan --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Android Developers group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~--~~~~--~~--~--~---