Memory leaks due to Android development coding specifications

Source: Internet
Author: User

In a long long time ago, read an article about memory leaks, which listed the comparison of the whole should pay attention to the problem, and later found not the original address, today turned the micro-bo, found the article, in order to facilitate future self-view, will pay attention to the problem extracted. In Android development, our coding habits may allow us to write code that is prone to memory leaks. So we should develop a good coding habit.

Single case

Normally, we might write a singleton like this.

 Public classsingleton{Private StaticSingleton instance;PrivateContext Mcontext;Private Singleton(Context Mcontext) { This. Mcontext = Mcontext; } Public StaticSingletongetinstance(Context context) {if(Instance = =NULL) {synchronized (Singleton.class) {if(Instance = =NULL) {instance =NewSingleton (context); }            }        }returnInstance }}

This can be a hidden problem because if we use Singleton.getinstance () in the activity or elsewhere, we will write this or mcontext (this variable also points to this) as a parameter to pass in. Our singleton is a singleton, meaning that it should always be in memory after initialization, so that we do not create the singleton object again when we call it later. However, the Mcontext variable in singleton always holds the context in the activity, causing the activity to destroy itself even if the OnDestroy method is executed. But the ApplicationContext is obviously different, it has been accompanied by our application, so there is no need to worry about the above-mentioned causes the activity cannot destroy the problem. So the correct wording was born.

 Public classsingleton{Private StaticSingleton instance;PrivateContext Mcontext;Private Singleton(Context Mcontext) { This. Mcontext = Mcontext; } Public StaticSingletongetinstance(Context context) {if(Instance = =NULL) {synchronized (Singleton.class) {if(Instance = =NULL) {instance =NewSingleton (Context.getapplicationcontext ()); }            }        }returnInstance }}
Anonymous inner class

In Android development, anonymous internal classes are used in many places, such as event snooping, handler message handling, and so on, which can lead to memory leaks when used incorrectly.

 Public  class mainactivity extends Activity{       PrivateButton btn;PrivateHandler Handler =NewHandler () {@override        Public void Handlermessage(Message msg) {          }    };@override     Public void onCreate(Bundle bundle) {Super. OnCreate (bundle);       Setcontextview (R.layout.activity_main);       Btn= (Button) Findviewbyid (R.ID.BTN); Btn.setonclicklistner (View.onclicklistener () {@override             Public void OnClick(View view)                {Message message = Message.obtain ();            Handler.sendmessage (message);    }       }); }}

When we execute the Mainactivity finish method, the deferred message is present in the main thread message queue for 10 minutes before it is processed, and the message contains the handler reference, and handler is an instance of an anonymous inner class. It holds a reference to the outside mainactivity, so this causes the mainactivity to not be recycled, which in turn causes mainactivity to have a lot of resources that cannot be recycled, resulting in a memory leak. However, a static anonymous inner class instance does not hold references to external classes. So the correct wording should be the case.

 Public  class mainactivity extends Activity{    PrivateButton btn;Private Static  class myhandler extends Handler {        Private FinalWeakreference<mainactivity> mactivity; Public MyHandler(mainactivity activity) {mactivity =NewWeakreference<mainactivity> (activity); }@Override         Public void Handlemessage(Message msg) {Mainactivity activity = mactivity.get ();if(Activity! =NULL) {// ...}        }    }Private FinalMyHandler handler =NewMyHandler ( This);@override     Public void onCreate(Bundle bundle) {Super. OnCreate (bundle);       Setcontextview (r.layout.activity_foo_layout);       Btn= (Button) Findviewbyid (R.ID.BTN); Btn.setonclicklistner (View.onclicklistener () {@override             Public void OnClick(View view)                {Message message = Message.obtain ();            Handler.sendmessage (message);    }       }); }}

Many times we even use handler to send an anonymous runnable object, which can also lead to memory leaks. Therefore, the Runnable object should also use static anonymous inner classes.

Private Static  class myrunnable implements Runnable{    PrivateWeakreference<textview> textviewweakreference; Public myrunnable(TextView TextView) {textviewweakreference =NewWeakreference<textview> (TextView); }@override     Public void Run(){FinalTextView TextView = Textviewweakreference.get ();if(TextView! =NULL) {Textview.settext ("OK"); }    };}

When you use it, that's it.

handler.postDelayed(new MyRunnable(textView),1000 * 60 * 10);
Handler

After using the handler, remember to call inside the OnDestroy

handler.removeCallbacksAndMessages(object token);

Removes the related message.

We can use

handler.removeCallbacksAndMessages(null);

When the argument is null, you can erase all runnable and message associated with the handler, and we will not have a memory leak if we call the secondary method in OnDestroy.

Make a summary of the above points
-Do not allow objects with a life cycle longer than the activity to hold references to activity
-Try to use application context instead of activity context
-Try not to use non-static inner classes in the activity, because non-static inner classes implicitly hold references to external class instances. If a static inner class is used, the external instance reference is held as a weak reference.
-Garbage collection does not resolve memory leaks, understanding the garbage collection mechanism in Android

Context

Notice the difference between context and ApplicationContext
-View.getcontext, which returns the context object of the current View object, usually the activity object currently being displayed.
-Activity.getapplicationcontext, gets the context object of the current Activity's (application) process, usually when we use the context object, the global process context is given precedence.
-Contextwrapper.getbasecontext (): Used to get a contextwrapper to decorate before the context, you can use this method, this method in the actual development of the use of not much, and is not recommended to use.
-Activity.this Returns the current activity instance, if the UI control needs to use Activity as the context object, but the default toast actually uses ApplicationContext.


It is important to note that some numbers have been added to some of them, but they are actually yes in terms of ability, but why no?
-Number 1: Startup activity is possible in these classes, but a new task needs to be created. Generally not recommended.
-Number 2: In these classes go to layout inflate is legal, but will use the system default theme style, if you customize some styles may not be used.
-Number 3: allowed when receiver is null, in version 4.2 or later, used to get the current value of the sticky broadcast. (Can be ignored)
Note: ContentProvider, broadcastreceiver in the above table, because there is a context in its internal method for use.

OK, here we look at the table, focusing on activity and application, you can see that the UI-related methods are not recommended or not to use application, and the first three operations are almost impossible to appear in application. In fact, as long as the grasp of a point, any UI-related, should use Activity as the context to deal with, and some other operations, service,activity,application and other instances can, of course, attention to the context of the holding of references, Prevent memory leaks.
For more detailed information on the context see Android context context you must know everything

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Memory leaks due to Android development coding specifications

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.