我有一个服务
,我希望它每秒更新主屏幕上的一个小部件。因此,服务监听每秒由 TimeController
发送的 OnTimerEvent。 TimeController
是一个包含运行 mUpdateTimeTask
的处理程序的单例:
public class TimeController {
private long startTime = -1;
// ... attributes ... listeners etc
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
TimeController.this.notify(new TimerUpdateEvent(this));
startTime += DateUtils.SECOND_IN_MILLIS;
mHandler.postAtTime(this, startTime);
}
};
public void startTimer() {
// if not already running
if (startTime == -1) {
startTime = SystemClock.uptimeMillis();
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 0);
}
};
// ...
}
这一切正常,小部件得到更新,但在 Logcat 中我看到:
12-10 22:06:42.825: DEBUG/dalvikvm(1738): GC freed 17488 objects / 651080 bytes in 112ms
12-10 22:06:44.035: DEBUG/dalvikvm(1738): GC freed 17479 objects / 650832 bytes in 172ms
12-10 22:06:45.205: DEBUG/dalvikvm(1738): GC freed 17428 objects / 649744 bytes in 97ms
12-10 22:06:46.315: DEBUG/dalvikvm(1738): GC freed 17463 objects / 650656 bytes in 86ms
12-10 22:06:47.725: DEBUG/dalvikvm(1738): GC freed 17793 objects / 663872 bytes in 85ms
12-10 22:06:48.985: DEBUG/dalvikvm(1738): GC freed 17026 objects / 633944 bytes in 176ms
12-10 22:06:50.145: DEBUG/dalvikvm(1738): GC freed 17492 objects / 651352 bytes in 89ms
12-10 22:06:51.674: DEBUG/dalvikvm(1738): GC freed 17435 objects / 650320 bytes in 105ms
12-10 22:06:52.934: DEBUG/dalvikvm(1738): GC freed 17519 objects / 652584 bytes in 109ms
12-10 22:06:54.234: DEBUG/dalvikvm(1738): GC freed 17487 objects / 650920 bytes in 90ms
12-10 22:06:55.645: DEBUG/dalvikvm(1738): GC freed 17685 objects / 659448 bytes in 91ms
而且我不喜欢我所看到的...:-)
public class MyService extends Service implements TimerUpdateListener {
@Override
public void onCreate() {
timeController = TimeController.getInstance();
timeController.addListener(this);
timeController.startTimer();
appWidgetManager = AppWidgetManager.getInstance(this);
remoteViews = new RemoteViews(this.getPackageName(), R.layout.widget_2x1);
projectWidget = new ComponentName(this, ProjectWidget.class);
super.onCreate();
}
@Override
public void onTimerUpdate(TimerUpdateEvent e) {
updateWidgetViews();
}
private void updateWidgetViews() {
// only update widgets if some exist
if (appWidgetManager.getAppWidgetIds(projectWidget).length > 0) {
remoteViews.setTextViewText(R.id.time, MyDateUtils.timeLeftAsString(project.getInCurrentLevelSince()));
appWidgetManager.updateAppWidget(projectWidget, remoteViews);
}
}
}
如果我注释掉 remoteViews.setTextViewText(...)
,则 GC 消息不会出现。那么如何在不发生如此巨大的内存泄漏的情况下更新 View 呢?
谢谢!
最佳答案
I have a Service and I want it to update a widget on the homescreen each second.
请不要那样做。应用程序小部件机制专为更新频率较低的内容而设计——例如,每半小时一次。如果这样做,您会将用户的电池敲成糊状,并从他们的前台应用程序中窃取 CPU 时间(例如,降低他们正在玩的游戏的帧速率)。
一旦您将更新频率降低到合理水平,请不要使用其唯一使命就是跟踪时间的服务。请改用 AlarmManager
。
So how can I update the view without having such a huge memory leaking?
根据定义,如果它正在被垃圾收集,则不是泄漏。当您分配未 垃圾回收的内存时会发生泄漏。因此,您不会泄漏内存。
Oh I forgot: Yes, I know that updates of widgets each second are not recommended, but I really need a update at least every 10 seconds.
您的用户确实需要他们的设备具有可接受的性能。您的用户不需要您消耗所有这些 CPU 和 RAM。这意味着您的用户需要在市场上给您一星评级,因为他们没有考虑他们的需求,只考虑您的需求,就好像您更重要一样比他们好。
至少,让它成为可配置的,这样用户才能真正控制您的应用是否值得您寻求的东西,而不是您向他们口述条款。
关于从服务更新 android 小部件 - 内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4413828/