IntentService — проблема с выпуском Wakelock

У меня есть приложение для будильника. Поток выглядит следующим образом:

WakefulBroadcastReceiver (приобретает wakelock) --->> Служба Intent -->> startActivity

public class AlarmService extends IntentService {
    protected void onHandleIntent(Intent intent) {
        Intent activityIntent = new Intent(this, TriggeredActivity.class);
        activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(activityIntent);

По сути, WakefulBroadcaseReceiver запускает службу намерений, используя startWakefulService(). Внутри службы намерений onHandleIntent() единственная работа, которую я делаю, — это запуск новой активности с использованием startActivity(). В этом новом действии я использую mediaPlayer в цикле, который подает сигнал тревоги. У этого действия есть кнопка закрытия, которая ожидает щелчка пользователя, чтобы остановить медиаплеер и завершить действие. Теперь проблема, с которой я столкнулся, заключается в том, что после вызова startactivity() внутри службы намерений я не могу дождаться завершения TriggeredActivity (нет эквивалента startActivityForResult в службе), а затем завершить намерение бодрствования. Связанная ссылка

startActivity(активностьIntent); WakefulBCastReceiver.completeWakefulIntent(намерение); /* здесь нельзя */

Поэтому я не отключаю здесь wakelock явным образом.

Мой вопрос в том, будет ли wakelock автоматически освобождаться (ссылка на смерть), когда процесс, который его удерживает, будет убит. Если да, то в моем конкретном сценарии мне не нужно вызывать WakefulBCastReceiver.completeWakefulIntent().


person gaurav.28ch    schedule 02.10.2016    source источник
comment
ваш процесс не убит, вам нужно release() ваш WakeLock   -  person pskink    schedule 02.10.2016


Ответы (2)


Да, вам нужно использовать completeWakefulIntent.

Вам нужно поместить свое намерение TriggeredActivity в EXTRA.

@Override
public void onReceive(Context context, Intent intent) {

    Intent intentService = new Intent(context, NotificationsIntentService.class);
    // Inserting data inside the Intent
    intentService.putExtra(NotificationsIntentService.EXTRA_NOTIF, new Intent(context, TriggeredActivity.class));
    startWakefulService(context, intentService);
}

NotificationsIntentService.class

public class NotificationsIntentService extends IntentService {

     private static final String TAG = "DebugNotifIntent";

     public static final String EXTRA_NOTIF = "extra_notif";

     public NotificationsIntentService(){
         super(NotificationsIntentService.class.getSimpleName());
     }

     @Override
     protected void onHandleIntent(Intent intent) {
          Log.d(TAG, "onHandleIntent: ");
          Intent extraIntent = intent.getParcelableExtra(EXTRA_NOTIF);
          extraIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
          startActivity(extraIntent);

          NotificationWakefulBroadcastReceiver.completeWakefulIntent(intent);
     }

     @Override
     public void onDestroy() {
         super.onDestroy();
         Log.d(TAG, "onDestroy: ");
     }
}
person aleksandrbel    schedule 02.10.2016

Мне удалось найти решение моей проблемы. Сейчас я использую Messenger для межпроцессного обмена сообщениями между службой намерений и инициируемой активностью. Я передаю обработчик - alarmServiceHandler, от сервиса намерений к активности через мессенджер.

Handler alarmServiceHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        if(msg.arg1 == 1) {
            completedTriggeredActivity = true;
        }
    }
};

Внутри onHandleIntent() я передаю обработчик через объект Messenger в дополнительных данных намерения.

    Messenger alarmServiceMessenger = new Messenger(alarmServiceHandler);
    Intent activityIntent = new Intent(this, TriggeredActivity.class);
    activityIntent.putExtra("AlarmServiceMessenger", alarmServiceMessenger);
    activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(activityIntent);


    while(!completedTriggeredActivity){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    WakefulBCastReceiver.completeWakefulIntent(intent);

В TriggeredActivity я получаю мессенджер в OnClickListener кнопки Dismiss непосредственно перед вызовом finish() для действия. И отправка обратно сообщения в AlarmService с arg = 1, подразумевающим завершение обработки в сработавшем действии.

buttonDismiss.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Messenger alarmServiceMessenger = getIntent().getParcelableExtra("AlarmServiceMessenger");
                Message alarmServiceMessage = Message.obtain();
                alarmServiceMessage.arg1 = 1;
                try {
                    alarmServiceMessenger.send(alarmServiceMessage);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }

                finish();

            }

После запуска триггерной активности я перевожу AlarmService в спящий режим до тех пор, пока логическая переменная completeTriggeredActivity не будет установлена ​​в значение true в handleMessage(). Когда это правда, это означает, что инициированная активность завершена, и теперь я могу приступить к снятию блокировки пробуждения.

Я был бы рад получить комментарии о моем подходе и любые предложения по лучшему решению моей проблемы, чем то, которое я придумал.

person gaurav.28ch    schedule 02.10.2016