【问题标题】:android memory leak in notification service通知服务中的android内存泄漏
【发布时间】:2011-03-24 08:20:36
【问题描述】:

我有一项服务,它创建一个通知,然后定期用某些信息更新它。大约 12 分钟左右后手机崩溃并重新启动,我相信这是由以下代码中的内存泄漏引起的,这与我如何更新通知有关,如果是这种情况,有人可以检查/建议我吗?我做错了。

创建:

mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

创建通知:

private void createNotification() {
  Intent contentIntent = new Intent(this,MainScreen.class);
  contentIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
  PendingIntent appIntent =PendingIntent.getActivity(this,0, contentIntent, 0);

  contentView = new RemoteViews(getPackageName(), R.layout.notification);
  contentView.setImageViewResource(R.id.image, R.drawable.icon);
  contentView.setTextViewText(R.id.text, "");

  notification = new Notification();
  notification.when=System.currentTimeMillis();
  notification.contentView = contentView;
  notification.contentIntent = appIntent;
}

更新通知:

private void updateNotification(String text){
  contentView.setTextViewText(R.id.text, text);
  mNotificationManager.notify(0, notification);
}

提前致谢。

【问题讨论】:

  • 请在重启前发布一些Logcat
  • 这只是 GC 越来越大,直到它引起问题并开始杀死东西并重新启动
  • 确保它确实是您的应用程序。尝试完全卸载它,看看它是否仍然发生。可能是您最近安装的其他应用。
  • 适用于我的应用,也出现在模拟器中。
  • 你确定是这个服务吗?就像你注释掉服务所做的一切一样,它仍然有同样的问题吗?

标签: android memory-leaks notifications notificationmanager


【解决方案1】:

我偶然发现了同样的问题。看起来如果您不在服务中“缓存”远程视图和通知,而是在“更新”例程中从头开始重新创建它们,这个问题就会消失。是的,我知道它效率不高,但至少手机不会因内存不足错误而重新启动。

【讨论】:

  • 嗯,奇怪,我会在假期后尝试确认。
  • 嗨,我正在使用服务连续(每秒之后)更新通知的远程视图(其中正好有 3 个文本视图)。手机变得超级慢并在一段时间后冻结。我也应该为这个问题重新创建通知吗?
  • @berserk,是的,你应该这样做。
  • @Sakiboy 正如你所说,不要经常更新它......但我正在使用进度来显示下载......所以我必须根据我的下载更新它......我能做什么?
  • @HRaval,在这里查看我的答案:stackoverflow.com/a/38402214/2371425。基本上,当且仅当进度实际发生变化时,您只想更新通知。
【解决方案2】:

我遇到了同样的问题。我的解决方案与@haimg 所说的接近,但我确实缓存了通知(只是重新创建了 RemoteView)。这样,如果您正在查看通知,通知将不会再次闪烁。

例子:

public void createNotification(Context context){
    Notification.Builder builder = new Notification.Builder(context);

    // Set notification stuff...

    // Build the notification
    notification = builder.build();
}

public void updateNotification(){
    notification.bigContentView = getBigContentView();
    notification.contentView = getCompactContentView();

    mNM.notify(NOTIFICATION_ID, notification);
}

getBigContentViewgetCompactContentView 方法中,我返回一个带有更新布局的新 RemoteViews

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-18
    • 2012-01-31
    • 2013-08-27
    • 2014-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多