Aug 5 2013

Binders & Death Recipients

Note: before you begin, make sure you’ve read my previous post about Binder tokens!

Since the very beginning, Android’s central focus has been the ability to multitask. In order to achieve it, Android takes a unique approach by allowing multiple applications to run at the same time. Applications are never explicitly closed by the user, but are instead left running at a low priority to be killed by the system when memory is low. This ability to keep processes waiting in the background speeds up app-switching later down the line.

Developers learn early on that the key to how Android handles applications in this way is that processes aren’t shut down cleanly. Android doesn’t rely on applications being well-written and responsive to polite requests to exit. Rather, it brutally force-kills them without warning, allowing the kernel to immediately reclaim resources associated with the process. This helps prevent serious out of memory situations and gives Android total control over misbehaving apps that are negatively impacting the system. For this reason, there is no guarantee that any user-space code (such as an Activity’s onDestroy() method) will ever be executed when an application’s process goes away.

Jul 31 2013

Binders & Window Tokens

Note: if you liked this post, be sure to read my second blog post about Binders & Death Recipients as well!

One of Android’s key design goals was to provide an open platform that doesn’t rely on a central authority to verify that applications do what they claim. To achieve this, Android uses application sandboxes and Linux process isolation to prevent applications from being able to access the system or other applications in ways that are not controlled and secure. This architecture was chosen with both developers and device users in mind: neither should have to take extra steps to protect the device from malicious applications. Everything should be taken care of automatically by the system.

For a long time I took this security for granted, not completely understanding how it was actually enforced. But recently I became curious. What mechanism prevents me from, for example, tricking the system into releasing a wake lock acquired by another application, or from hiding another application’s windows from the screen? More generally, how do Android’s core system services respond to requests made by third-party applications in a way that is both efficient and secure?

Apr 29 2013

Handling Configuration Changes with Fragments

This post addresses a common question that is frequently asked on StackOverflow:

What is the best way to retain active objects—such as running Threads, Sockets, and AsyncTasks—across device configuration changes?

To answer this question, we will first discuss some of the common difficulties developers face when using long-running background tasks in conjunction with the Activity lifecycle. Then, we will describe the flaws of two common approaches to solving the problem. Finally, we will conclude with sample code illustrating the recommended solution, which uses retained Fragments to achieve our goal.

Apr 15 2013

Activitys, Threads, & Memory Leaks

Note: the source code in this blog post is available on GitHub.

A common difficulty in Android programming is coordinating long-running tasks over the Activity lifecycle and avoiding the subtle memory leaks which might result. Consider the Activity code below, which starts and loops a new thread upon its creation:

/**
 * Example illustrating how threads persist across configuration
 * changes (which cause the underlying Activity instance to be
 * destroyed). The Activity context also leaks because the thread
 * is instantiated as an anonymous class, which holds an implicit
 * reference to the outer Activity instance, therefore preventing
 * it from being garbage collected.
 */
public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    exampleOne();
  }

  private void exampleOne() {
    new Thread() {
      @Override
      public void run() {
        while (true) {
          SystemClock.sleep(1000);
        }
      }
    }.start();
  }
}
Jan 14 2013

How to Leak a Context: Handlers & Inner Classes

Consider the following code:

public class SampleActivity extends Activity {

  private final Handler mLeakyHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
      // ... 
    }
  };
}

While not readily obvious, this code can cause cause a massive memory leak. Android Lint will give the following warning:

In Android, Handler classes should be static or leaks might occur.

But where exactly is the leak and how might it happen? Let’s determine the source of the problem by first documenting what we know:

+1 this blog!

Android Design Patterns is a website for developers who wish to better understand the Android application framework. The tutorials here emphasize proper code design and project maintainability.

Find a typo?

Submit a pull request! The code powering this site is open-source and available on GitHub. Corrections are appreciated and encouraged! Click here for instructions.

Apps by me

2048++ is hands down the cleanest, sleekest, most responsive 2048 app for Android! Play Store