Утечка памяти Android в службе уведомлений

У меня есть служба, которая создает уведомление, а затем периодически обновляет его определенной информацией. Примерно через 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);
}

Заранее спасибо.


person stealthcopter    schedule 02.08.2010    source источник
comment
Пожалуйста, опубликуйте некоторые из Logcat прямо перед перезагрузкой   -  person smith324    schedule 28.08.2010
comment
Просто GC становится все больше и больше, пока не вызывает проблемы, не начинает убивать и перезагружаться.   -  person stealthcopter    schedule 29.08.2010
comment
Убедитесь, что это точно ваше приложение. Попробуйте полностью удалить его и посмотреть, если это все еще происходит. Возможно, это какое-то другое приложение, которое вы недавно установили.   -  person Moncader    schedule 30.08.2010
comment
Это для моего приложения, встречается и в эмуляторах.   -  person stealthcopter    schedule 30.08.2010
comment
Вы уверены, что это эта служба? Например, если вы закомментируете все, что делает служба, останется ли у нее та же проблема?   -  person fredley    schedule 31.08.2010
comment
Я опубликовал очень похожий случай с кодом и выводом logcat здесь: › stackoverflow.com/q/3608684/435855 Надеюсь, это помогает   -  person Urizev    schedule 31.08.2010
comment
Вы где-нибудь видите OutOfMemoryError? Либо в виде всплывающего окна, либо в Logcat?   -  person gary    schedule 03.09.2010
comment
Я сам видел такое же поведение - решение состояло в том, чтобы удалить индикатор выполнения.   -  person plouh    schedule 14.09.2010
comment
То же самое здесь, но телефон не перезагружается. Только уведомление через некоторое время зависает.   -  person Martin Pfeffer    schedule 11.04.2017


Ответы (2)


Я наткнулся на ту же проблему. Похоже, что если вы не «кэшируете» RemoteView и Notification в службе, а воссоздаете их с нуля в процедуре «обновления», эта проблема исчезает. Да, я знаю, что это неэффективно, но по крайней мере телефон не перезагружается из-за ошибок нехватки памяти.

person haimg    schedule 19.12.2010
comment
Хм, странно, я попробую это после праздников, чтобы подтвердить. - person stealthcopter; 23.12.2010
comment
Привет, я постоянно (после каждой секунды) обновляю удаленный просмотр уведомлений (точно 3 текстовых представления внутри него) с помощью службы. Телефон становится очень медленным и через некоторое время зависает. Должен ли я воссоздать уведомление и для этой проблемы? - person berserk; 09.01.2014
comment
@berserk, да, ты должен. - person grepsedawk; 10.03.2014
comment
@Sakiboy, как вы сказали, не обновляйте его слишком часто ... но я использую прогресс, чтобы показать загрузку ... поэтому мне нужно обновить его в соответствии с моей загрузкой ... что я могу сделать? - person H Raval; 05.08.2016
comment
@HRaval, посмотрите мой ответ здесь: stackoverflow.com/a/38402214/2371425. По сути, вы хотите обновить уведомление только в том случае, если прогресс действительно изменился. - person Sakiboy; 09.08.2016

У меня была такая же проблема. Мое решение близко к тому, что сказал @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);
}

А в методах getBigContentView и getCompactContentView возвращаю новый RemoteViews с обновленным макетом.

person Alesqui    schedule 09.05.2013