从服务更新 android 小部件 - 内存泄漏?

标签 android service timer widget

我有一个服务,我希望它每秒更新主屏幕上的一个小部件。因此,服务监听每秒由 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/

相关文章:

android - Badtokenexception androidx

java - 如果警报日期等于当前日期,我想创建通知,并且通知将创建从警报日期到疫苗日期的所有日期

android - 如何从 html 链接启动 Android 服务?

c - C中的阻塞/非阻塞定时器

java - String.format 不适用于计时器应用程序中的参数

android - 图像/文本在背景中居中的按钮

android 10 在通知上搜索栏

c++ - 有没有办法允许 Windows 服务(非托管 C++)在共享网络文件夹上写入文件?

android - 在 onSensorChanged 上读取数据时出现问题

java - 如何创建像电话一样的秒/毫秒计时器?