У меня есть Service
, и я хочу, чтобы он обновлял виджет на главном экране каждую секунду. Поэтому служба прослушивает OnTimerEvent, который отправляется TimeController
каждую секунду. TimeController
одноэлементно держит обработчик, который работает mUpdateTimeTask
:Обновление виджета Android от службы - утечка памяти?
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(...)
ГЦ сообщения не отображаются. Итак, как я могу обновить представление без утечки огромной памяти?
Спасибо!
О, я забыл: Да, я знаю, что обновление виджета каждую секунду не рекомендуется, но мне действительно нужно обновление не реже одного раза в 10 секунд. В любом случае, я задаюсь вопросом, является ли этот GC утечкой памяти или если это вызвано часто обновлениями? – Stuck
Я предполагаю, что что-то выделяется в MyDateUtils.timeLeftAsString(); - Могли бы вы опубликовать эту функцию? – danh32
@ danh32, если я прокомментирую это и поставлю туда фиксированную строку, произойдет такое же распределение. – Stuck