More content, access to personal blogs www.liangfeizc.com error codes
If a variable Runnable is defined in Activiy by an inner class (Runnable),
Final Runnable Runnable = new Runnable () {public void run () { //... do some work }};handler.postdelayed (Runn Able, TimeUnit.SECONDS.toMillis (10)
Because runnable is not a static type, there is a implicit reference ---activity.this that contains an Activity instance.
If the activity is removed before the runnable variable run (10s) but the activity.this still exists, the activity object will not be recycled by GC, resulting in memory leak.
Even with a static inner class, there is no guarantee that everything is going to work.
Static Class Myrunnable implements Runnable { private view view; Public myrunnable (view view) { This.view = view; } public void Run () { //... do something with the View }}
It is assumed that the view was removed before Runnable was executed, but the member variable view continues to reference it, still causing the memory leak.
In the two examples above, the two usages that lead to memory leaks are implicit references (implicit reference) and Explicit references (explicit reference).
Workaround
The method of resolving implicit references is simple, as long as you use an internal non-static class (Non-static inner Class) or top-level class(a variable defined in a separate Java file) to make implicit explicit, thus avoiding memory leaks.
If you continue to use non-static inner classes, you should manually end those pending tasks (pending task) at OnPause.
For information on how to end any, handler can refer to canceling a pending Runnable and cancelingpending Messages in this article. Handlerthread can refer to this article.
Solve the second problem to use weakreference, weakreference usage can Google, in short: As long as there are other stronger reference, WeakReference can continue to reference.
Static Class Myrunnable implements Runnable { private weakreference>view< View; Public myrunnable (view view) { This.view = new weakreference>view< (view); } public void Run () { View v = view.get (); if (v! = null) { //... do something with the View }} }
This solves the problem, the drawback is that each time you use the view to short the pointer to judge. Another efficient way is to assign a value of runnable to the view in Onresume, and assign null in OnPause.
private static class MyHandler extends Handler { private TextView view; public void Attach (TextView view) { This.view = view; } public void Detach () { view = null; } @Override public void Handlemessage (Message msg) { //... }
Summarize
At the time of inheriting handler or Handlerthread,
- Try to define a static class or top-level class.
- If UI elements are used, be sure to release them before the activity's life cycle contact.
Reference
Asynchronous Android-steve Liles
How to avoid handler causing memory leaks in Android