У меня есть служба переднего плана, которая подает сигнал тревоги в течение одной минуты, а затем закрывается сама. Я использую 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 для утечки памятиобнаружение.