2. Common causes of memory leaks
Which Context to use?
Application Context
Activity Context
Problem with references outside of context
Why should Handlers be static?
Should inner classes be static?
Recycle bitmaps
3. Common causes of memory leaks
Which Context to use?
Application Context
Activity Context
Problem with references outside of context
Why should Handlers be static?
Should inner classes be static?
Leaking Threads
Also, Recycling Bitmaps (not covered here).
4. Which Context?
Which is better?
1. new ArrayAdapter(this, android.R.layout.simple_list_item_1, list);
2. new ArrayAdapter(getApplicationContext(), android.R.layout.simple_list_item_1, list);
3. new ArrayAdapter(getBaseContext(), android.R.layout.simple_list_item_1, list);
1. new TextView(this);
2. new TextView(getApplicationContext());
3. new TextView(getBaseContext());
5. Which is better?
1. new ArrayAdapter(this, android.R.layout.simple_list_item_1, list);
2. new ArrayAdapter(getApplicationContext(), android.R.layout.simple_list_item_1, list);
3. new ArrayAdapter(getBaseContext(), android.R.layout.simple_list_item_1, list);
1. new TextView(this);
2. new TextView(getApplicationContext());
3. new TextView(getBaseContext());
6. Good rule of thumb
Always use Application Context.
Use Activity where necessary. Meaning the object will be
collected with the Activity or method specifically requests
it.
Never use getBaseContext().
7. Problem with references outside context
Why using the right context is important?
Threads & Garbage Collection
How do we fix this?
8. Usually not a problem
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
TextView label = new TextView(this);
label.setText("Leaks are bad");
setContentView(label);
}
//Code by Romain Guy
9. Now it’s a problem
private static Drawable sBackground;
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
TextView label = new TextView(this);
label.setText("Leaks are bad");
if (sBackground == null) {
sBackground = getDrawable(R.drawable.large_bitmap);
}
label.setBackgroundDrawable(sBackground);
setContentView(label);
}
//Code by Romain Guy
Drawables hold references to
the Activity.
TextView holds a strong
reference to the Activity. The
Drawable is not garbage
collected, as a result, neither
is the TextView or the
Activity.
10. The problem with non-static inner
classes
Why do I get this error?
12. So whats the issue with non-static inner
classes
When an Android application first starts, the framework creates a Looper object
for the application's main thread. A Looper implements a simple message queue,
processing Message objects in a loop one after another. All major application
framework events (such as Activity lifecycle method calls, button clicks, etc.)
are contained inside Message objects, which are added to the Looper's message
queue and are processed one-by-one. The main thread's Looper exists throughout
the application's lifecycle.
When a Handler is instantiated on the main thread, it is associated with the
Looper's message queue. Messages posted to the message queue will hold a
reference to the Handler so that the framework can call
Handler#handleMessage(Message) when the Looper eventually processes the
message.
In Java, non-static inner and anonymous classes hold an implicit reference to
their outer class. Static inner classes, on the other hand, do not.
13. So what’s the issue with Threads?
Threads can be leaked along with/without
memory.
Why?
Threads in Java are GC roots; that is, the Dalvik Virtual
Machine (DVM) keeps hard references to all active
threads in the runtime system, and as a result, threads
that are left running will never be eligible for garbage
collection.
14. Crouton
Why do we have to call
Crouton.cancelAllCroutons()
?
15. Crouton
Why do we have to call
Crouton.cancelAllCroutons()
?
16. What can we do?
Do not reference anything outside of it’s scope.
Try to not have long living objects.
Don’t assume java will clean up your threads.
Implement cancellation policies for background threads.
WeakReference