在我的应用程序中,我有一个(后台)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...
}
我的 Activity
在 onStart
中连接到此 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/