Почему объект Service не подвергается сборке мусора, несмотря на использование WeakReference? - PullRequest
2 голосов
/ 21 октября 2019

У меня есть служба переднего плана, которая подает сигнал тревоги в течение одной минуты, а затем закрывается сама. Я использую Handler для закрытия службы через одну минуту, публикуя отложенное сообщение.
Класс Handler использует одноэлементный подход (по причине, которая не относится к этому сообщению). Хотя код работает нормально, проблема в том, что служба не получает мусор даже после вызова метода onDestroy ().

Ниже приведен код: -

AlarmService.java: -

public class AlarmService extends Service {
private MediaPlayer alarm;
private AlarmHandler alarmHandler;
private static final int DELAY = 60 * 1000;

//onBind method

@Override
public void onCreate() {
    super.onCreate();
    alarmHandler = AlarmHandler.getInstance();
    alarmHandler.attachService(this);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    clearPreviousAlarms();          //if any
    alarm = MediaPlayer.create(this, R.raw.kalimba);
    startForeground(1, NotificationUtil.buildNotification(this));
    alarm.start();
    alarmHandler.sendEmptyMessageDelayed(1, DELAY);

    return START_NOT_STICKY;
}

private void clearPreviousAlarms() {
    if (alarm != null) {
        alarm.release();
    }
    if (alarmHandler.hasMessages(1)) {
        alarmHandler.removeMessages(1);
    }

}

@Override
public void onDestroy() {
    super.onDestroy();
    MyApp.refWatcher.watch(this);    //using leakCanary for detecting the memory leak
    alarm.release();
    if (alarmHandler.hasMessages(1))
        alarmHandler.removeMessages(1);
}

}

AlarmHandler.java: -

class AlarmHandler extends Handler {
private static AlarmHandler alarmHandler;
private WeakReference<AlarmService> alarmService;

private AlarmHandler() {
}

public void attachService(AlarmService alarmService) {
    this.alarmService = new WeakReference<AlarmService>(alarmService);
}

public static AlarmHandler getInstance() {
    if (alarmHandler == null) {
        alarmHandler = new AlarmHandler();
    }
    return alarmHandler;
}

@Override
public void handleMessage(Message msg) {
    switch (msg.what) {
        case 1: {
            alarmService.get().stopSelf();
        }
        break;
    }
}

}

ПРИМЕЧАНИЕ: -

  • Как вы можете видеть выше, утечка памяти все еще вызывается, несмотря на используемую WeakReference.

  • Я использую LeakCanary для утечки памятиобнаружение.

...