我有一个服务在 GameLogic
单例中调用一些更新方法。 GameLogic
可能会决定需要进行某些状态更新。在这种情况下,它会通知监听器有关 StatusUpdateEvent
的信息。然后听众更新他们的 View 等。
public class GameLogic {
// ... attributes ...
private static GameLogic instance = null;
private GameLogic() {
// singleton pattern
}
public static synchronized GameLogic getInstance() {
if (instance == null) {
instance = new GameLogic();
}
return instance;
}
public void checkStatus() {
// called by service
// ... some checks
notifyStatusUpdate(new StatusUpdateEvent());
}
public void addStatusUpdateListener(StatusUpdateListener listener) {
if (!listeners.contains(listener)) {
listeners.add(listener);
}
}
public void removeStatusUpdateListener(StatusUpdateListener listener) {
listeners.remove(listener);
}
protected synchronized void notifyStatusUpdate(StatusUpdateEvent event) {
for (StatusUpdateListener l : listeners) {
l.onStatusUpdate(event);
}
}
}
我有一个应该监听StatusUpdateEvent
的小部件:
public class ProjectWidget extends AppWidgetProvider implements StatusUpdateListener {
// ... attributes ...
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
this.context = context;
this.appWidgetManager = appWidgetManager;
this.remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_2x1);
this.thisWidget = new ComponentName(context, ProjectWidget.class);
GameLogic.getInstance().addStatusUpdateListener(this);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
Toast.makeText(context, "onDeleted", Toast.LENGTH_SHORT).show();
GameLogic.getInstance().removeStatusUpdateListener(this);
super.onDeleted(context, appWidgetIds);
}
@Override
public void onStatusUpdate(StatusUpdateEvent e) {
android.util.Log.d("ProjectWidget", "onStatusUpdate");
// here some class fields are updated like this.project = e.getProject();
// ...
updateViews();
appWidgetManager.updateAppWidget(thisWidget, remoteViews);
}
// ... updateViews() etc.
}
但是现在的问题是: 我将小部件添加到主屏幕,一切都很好。然后,如果我从主屏幕删除小部件,我会看到 onDelete Toast,但之后我仍然会看到该日志条目:ProjectWidget onStatusUpdate。
所以监听器没有被删除..为什么?我该如何做这些事情?
谢谢!
最佳答案
So the listener is not removed.. why? and how can I do that stuff?
你遇到的是内存泄漏。
AppWidgetProvider
是一个 transient 对象。它将存活足够长的时间来处理 onUpdate()
或其他应用程序小部件生命周期方法,然后它就会消失。
永远永远永远永远永远永远永远尝试让AppWidgetProvider
的生命周期比这更长,例如按原样将其注册在静态上下文中。您正在泄漏内存,因为 AppWidgetProvider
不会被垃圾收集。
当您调用 removeStatusUpdateListener()
时,您拥有的 AppWidgetProvider
实例与您在 addStatusUpdateListener()
中使用的实例不同。因此,删除操作是一个无操作(您正在删除从未注册的内容),并且原始监听器将永远保留在那里。
让您的 GameLogic
或其他任何内容直接更新您的应用小部件 RemoteViews
。
关于onDelete 后的 android 小部件仍在监听,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4408184/