android - Activity和Service之间的通信导致内存泄漏

标签 android android-service aidl

在我的应用程序中,我有一个(后台)Service,它在自己的进程中运行。为了与其他组件通信,我定义了一些 AIDL 接口(interface):

interface MyService {
    void addOnChangeListener(ServiceChangedListener listener);
    void removeOnChangeListener(ServiceChangedListener listener);
}

interface ServiceChangedListener {
    void onUserChanged(in User newUser);
}

这是我的带有 MyService 实现的服务。

public class UserService extends Service {
    private RemoteCallbackList<ServiceChangedListener> listeners;

    public class ServiceBinder extends MyService.Stub {
        public void addOnChangeListener(ServiceChangedListener listener) {
            listeners.register(listener);
        }

        public void removeOnChangeListener(ServiceChangedListener listener) {
            listeners.unregister(listener);
        }
    }

    // all the other implementation...
}

我的 ActivityonStart 中连接到此 Service,并在 onStop 中断开连接,同时释放在 onServiceConnected 中注册的监听器。

public class MainAcitivity extends AppCompatActivity {
    private ServiceListener listener;
    private MyService service;

    protected void onStart() {
        super.onStart();

        Intent intent = new Intent(this, UserService.class);
        bindService(intent, this, Context.BIND_AUTO_CREATE);
    }

    protected void onStop() {
        super.onStop();

        try { service.removeOnChangeListener(listener); }
        catch (RemoteException e) { e.printStackTrace(); }

        unbindService(this);
    }

    public void onServiceConnected(ComponentName className, IBinder service) {
        service = MyService.Stub.asInterface(service);

        try {
            listener = new ServiceListener();
            service.addOnChangeListener(listener);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    private class ServiceListener extends ServiceChangedListener.Stub {
        public void onUserChanged(User u) throws RemoteException {
            runOnUiThread(() -> { ... });
        }
    }
}

正如您所期望的那样,监听器的添加和删除方法只需在 ArrayList 上进行操作,因此无需长时间进行工作。

LeakCanary 以及 Android studio 内存分析工具告诉我,这会导致内存泄漏。如果我注释掉影响监听器的行,则不会检测到内存泄漏。你知道为什么吗?

最佳答案

我终于找到答案了!您必须使内部类静态并在其中使用WeakReference。这是一个official answer一位 Google 工程师和 here一种简化的。祝遇到同样问题的人好运!

关于android - Activity和Service之间的通信导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49219106/

相关文章:

android - 如何在 Android 上使用 IntentService 实现回调?

Android使用intent设置壁纸

android - 如何在 ListView 中获取文本

Android Location Listener 调用非常频繁

java - 单独文件中的 Android 服务不起作用

java - 从Service类中的BaseAdapter获取数据

android - 如何在 .aidl 文件中导入第三方类

android - 将 Square Picasso 的缓存大小限制为最大 60MB

android 服务通知 Activity 完成的最佳方式?

android - 在进程之间共享 Activity 对象的正确方法是什么?