First look at a set of simple code
- public class SampleActivity extends Activity {
-
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- // ...
- }
- }
- }
-
When we writeActivity
Medium,Android Lint
Will prompt us suchWarning: In Android, Handler classes should be static or leaks might occur.
.
Meaning:In Android, the Handler class should be static; otherwise, leakage may occur.
Why?
Learn moreHandler
What causes memory leakage? Let's look at the following code.
- Public class SampleActivity extends Activity {
-
- Private final Handler mHandler = new Handler (){
- @ Override
- Public void handleMessage (Message msg ){
- //...
- }
- }
-
- @ Override
- Protected void onCreate (Bundle savedInstanceState ){
- Super. onCreate (savedInstanceState );
-
- // Send a message that is executed 10 minutes later
- MHandler. postDelayed (new Runnable (){
- @ Override
- Public void run (){}
- },600000 );
-
- // End the current Activity
- Finish ();
- }
- }
WhenActivity
AfterMessage queueProcess thisMessage
Previously, it will survive. ThisMessage
HoldHandler
AndHandler
YesActivity
(SampleActivity) reference, thisActivity
All resources cannot be recycled before message processing, So memory leakage occurs.
The solution is as follows:
- Public class SampleActivity extends Activity {
-
- /**
- * Using static internal classes does not hold the reference of the current object
- */
- Private static class MyHandler extends Handler {
- Private final WeakReference <SampleActivity> mActivity;
-
- Public MyHandler (SampleActivity activity ){
- MActivity = new WeakReference <SampleActivity> (activity );
- }
-
- @ Override
- Public void handleMessage (Message msg ){
- SampleActivity activity = mActivity. get ();
- If (activity! = Null ){
- //...
- }
- }
- }
-
- Private final MyHandler mHandler = new MyHandler (this );
-
- /**
- * Using static internal classes does not hold the reference of the current object
- */
- Private static final Runnable sRunnable = new Runnable (){
- @ Override
- Public void run (){}
- };
-
- @ Override
- Protected void onCreate (Bundle savedInstanceState ){
- Super. onCreate (savedInstanceState );
-
- // Send a message that is executed 10 minutes later
- MHandler. postDelayed (sRunnable, 600000 );
-
- // End
- Finish ();
- }
- }
OK, end
NOTE:Many people worry about weak references.Activity
We don't have to worry about recycling, because in this interfaceActivity
It won't be recycled. Think about it.If our Activity is recycled, how does this interface exist?
NOTE2:Ladies and gentlemen, referAsyncTask
. Check the document and your own understanding. I still hope you will forgive me for any errors.
NOTE3:I am not clear about how to prevent leaks,Handler
Below is a piece of source code
- final Class<? extends Handler> klass = getClass();
- if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
- (klass.getModifiers() & Modifier.STATIC) == 0) {
- Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
- klass.getCanonicalName());
- }
-