| Start |
|---|
| Avoid leaking Activities with AsyncTask A word of caution: AsyncTask has many gotcha's (opens new window) apart from the memory leak described here. So be careful with this API, or avoid it altogether if you don't fully understand the implications. There are many alternatives (Thread, EventBus, RxAndroid, etc). One common mistake with This is a problem because The right way to do this is to make your task a |
Common memory leaks and how to fix them 1. Fix your contexts:Try using the appropriate context: For example since a Toast can be seen in many activities instead of in just one, use Use this table as a quick guide for what context is appropriate:
Original article on context here (opens new window). 2. Static reference to ContextA serious memory leak mistake is keeping a static reference to Make sure there is absolutely no static reference to View, Context or any of their descendants. 3. Check that you're actually finishing your services.For example, I have an intentService that uses the Google location service API. And I forgot to call 4. Check image and bitmaps usage:If you are using Square's library Picasso I found I was leaking memory by not using the 5. If you are using broadcast receivers unregister them. 6. If you are using |
| Detect memory leaks with the LeakCanary library LeakCanary (opens new window) is an Open Source Java library to detect memory leaks in your debug builds. Just add the dependencies in the Then in your Now LeakCanary will automatically show a notification when an activity memory leak is detected in your debug build. NOTE: Release code will contain no reference to LeakCanary other than the two empty classes that exist in the |
| Anonymous callback in activities Every Time you create an anonymous class, it retains an implicit reference to its parent class. So when you write: You are in fact sending a reference to your LeakyActivity instance to foo. When the user navigates away from your LeakyActivity, this reference can prevent the LeakyActivity instance from being garbage collected. This is a serious leak as activities hold a reference to their entire view hierarchy and are therefore rather large objects in memory. How to avoid this leak: You can of course avoid using anonymous callbacks in activities entirely. You can also unregister all of your callbacks with respect to the activity lifecycle. like so: |
| Activity Context in static classes Often you will want to wrap some of Android's classes in easier to use utility classes. Those utility classes often require a context to access the android OS or your apps' resources. A common example of this is a wrapper for the SharedPreferences class. In order to access Androids shared preferences one must write:
And so one may be tempted to create the following class: now, if you call How to avoid: When calling static helper functions, you can send in the application context using When creating static helper functions, you can extract the application context from the context you are given (Calling getApplicationContext() on the application context returns the application context). So the fix to our wrapper is simple: If the application context is not appropriate for your use case, you can include a Context parameter in each utility function, you should avoid keeping references to these context parameters. In this case the solution would look like so: |
| Avoid leaking Activities with Listeners If you implement or create a listener in an Activity, always pay attention to the lifecycle of the object that has the listener registered. Consider an application where we have several different activities/fragments interested in when a user is logged in or out. One way of doing this would be to have a singleton instance of a Then there are two activities, And What happens with this example is that every time the user logs in and then logs out again, a Please note: Even if we use an anonymous inner class as a listener, the activity would still leak: The activity would still leak, because the anonymous inner class has an implicit reference to the outer class (in this case the activity). This is why it is possible to call instance methods in the outer class from the inner class. In fact, the only type of inner classes that do not have a reference to the outer class are static inner classes. In short, all instances of non-static inner classes hold an implicit reference to the instance of the outer class that created them. There are two main approaches to solving this, either by adding a method to remove a listener from Alternative 1: Removing listenersLet us start by creating a new method Then let us call this method in the activity's With this modification the instances of Alternative 2: Using weak referencesFirst off, let us start by explaining what a weak reference is. A weak reference, as the name suggests, holds a weak reference to an object. Compared to a normal instance field, which is a strong reference, a weak references does not stop the garbage collector, GC, from removing the objects. In the example above this would allow In short, a weak reference is telling the GC that if no one else has a strong reference to this object, go ahead and remove it. Let us modify the With this modification it doesn't matter whether or not the listeners are removed, since Now let us re-write As shown in the code example above, the |
| Avoid memory leaks with Anonymous Class, Handler, Timer Task, Thread
How do we solve it?
|
Read Article
https://develop.horje.com/learn/1434/reference