3

I have a LocalService implementation exactly as suggested here in order to provide access to service methods through the binder.

https://developer.android.com/guide/components/bound-services#Binder

public class LocalService extends Service {
    // Binder given to clients
    private final IBinder binder = new LocalBinder();

    /**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    public class LocalBinder extends Binder {
        LocalService getService() {
            // Return this instance of LocalService so clients can call public methods
            return LocalService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }
}

Starting Android 10 this implementation seems to leak memory. When the service is unbound (and destroyed) the LocalService and LocalBinder objects are not garbage collected. The next bind creates a new service object. According to the memory profiler the LocalBinder object is referent in Cleaner. Any idea how to fix?

Alexey Ozerov
  • 1,398
  • 13
  • 23

1 Answers1

1

A bit late but here it is. Binders are not tied to the lifecycle of components (e.g. services). The instance of a Binder is kept around internally in case some other process/thread calls the Binder's transact method.

In your code, LocalBinder is an inner class. Therefore, implicitly LocalBinder has a reference to LocalService. So even though the LocalService may have been destroyed, its reference is still contained inside of the LocalBinder, thereby leaking the LocalService.

The solution is to make LocalBinder a static class (or an entirely separate class) and use a WeakReference for your LocalService.

I am aware that your code comes straight from the Android Documentation, but it is still wrong. In fact, if you want to go looking, there is an old bug report where the Android team acknowledges this and then marks the bug as "Obsolete (Won't Fix)" because the team has decided to go in a different direction -- I have no clue what that means only that they won't be changing it in the near future. Link to the Android Issuetracker.

Robin
  • 3,512
  • 10
  • 39
  • 73