[android-developers] Re: Memory Leak when creating OnClickListener

2009-08-17 Thread Dan Sherman
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

2009-08-17 Thread Dianne Hackborn
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

2009-08-17 Thread Dan Sherman
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

2009-08-17 Thread Dianne Hackborn
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

2009-08-17 Thread Dan Sherman
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

2009-08-17 Thread Romain Guy

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

2009-08-17 Thread Romain Guy

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

2009-08-17 Thread Dan Sherman
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

2009-08-15 Thread Balwinder Kaur (T-Mobile USA)

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

2009-08-15 Thread Dan Sherman
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
-~--~~~~--~~--~--~---