привязка к работающему Сервису (после finish ()) / обработчику обратного вызова - PullRequest
5 голосов
/ 16 марта 2012

Опять вопрос про LocalServices.Как (повторно) привязать существующую службу после onDestroy ()?

Проблема: Я привязываюсь к службе и запускаю службу из действия.Я отправляю работающие объекты в Binder для обратного вызова (обновление индикатора выполнения) в пользовательском интерфейсе.Когда я закрываю это действие, ОС может завершить жизненный цикл и уничтожить действие, вызывая onDestroy (), верно?Я имитирую это, вызывая finish () в методе onPause ().Итак, как только я перезапускаю Activity, как мне снова привязаться к той же самой службе?Я думал, что Сервисы - это Сингелтон, но когда я пытаюсь повторно связать, я получаю еще одну ссылку на связующее.Так что binder.callbackHandler.post(binder.progressHandler); по-прежнему имеет ссылку на старый binder / callback / progressHandler, а не на мой новый.Даже Конструктор Сервиса вызывается снова!

Есть ли какое-либо решение, чтобы иметь индикатор выполнения, обновляющийся объектами обратного вызова из сервиса (работает).Закрытие / onDestroy () Активность.Вернитесь и продолжите индикатор выполнения?

Мой код довольно большой, но воссоздан сценарий:

    public class MyService extends Service {
        private final LocalBinder binder = new LocalBinder();

        public class LocalBinder extends Binder implements TestRunServiceBinder {
            private Handler callbackHandler;
            private ServiceStartActivity.RunOnServiceProgress onProgress;

            @Override
            public void setActivityCallbackHandler(Handler messageHandler) {
                callbackHandler = messageHandler;
            }

            @Override
            public void setServiceProgressHandler(RunOnServiceProgress runnable) {
                onProgress = runnable;
            }

                public void doSomething(){
                     _doSomething();

        };

       private void _doSomething(){
        while(...){
           //do this a couple of times (could take up to 10min)
           binder.callbackHandler.post(binder.progressHandler);
           wait()
        }
      }

    }

_

public class ServiceStartActivity{
 private final Handler messageHandler = new Handler();
     private ServiceConnection mTestServiceConnection = new ServiceConnection() {


        @Override
        public void onServiceDisconnected(ComponentName name) {
            testRunBinder = null;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            testRunBinder = (TestRunServiceBinder) service;
            testRunBinder.setActivityCallbackHandler(messageHandler);
            testRunBinder.setServiceProgressHandler(new RunOnServiceProgress());
        }
      };

     @Override
     protected void onStart() {
    super.onStart();

    // bind to the Service
    final Intent serviceIntent = new Intent(ServiceStartActivity.this,
            MyService.class);
    getApplicationContext().bindService(serviceIntent,
            mTestServiceConnection, Context.BIND_AUTO_CREATE);

     }
    @Override
     protected void onStop() {
    super.onStop();
    getApplicationContext().unbindService(mTestServiceConnection);
    }
       public class RunOnServiceProgress implements Runnable {
            @Override
            public void run() {
                //do something on the UI!
                    }
        }
}

1 Ответ

8 голосов
/ 16 марта 2012

Я понял это сейчас.Решение заключается в явном вызове startService(serviceIntent); перед тем, как связываться с Сервисом, используя getApplicationContext().bindService(serviceIntent,mTestServiceConnection, Context.BIND_AUTO_CREATE);

Причина: Когда вы запускаете Сервис с bindService(), он становится Связанным Сервисом и

работает только до тех пор, пока к нему привязан другой компонент приложения.

Если вы запускаете службу с startService(), она может

может работать в фоновом режиме бесконечно,

Так что, если у вас есть, например, панель progessbar в пользовательском интерфейсе, и вы хотите, чтобы она продолжала обновлять ее, вы должны запустить службу и связать и отменить привязку в onResume () / onPause ().Но будьте осторожны: поскольку вы запустили Сервис вручную, Вам также следует остановить его вручную .Самый простой способ сделать это - позвонить по номеру stopSelf(), как только Служба выполнит свою работу.

Этот заголовок покрывает надлежащую привязку из Действия с, например, индикатором прогресса к той же Службе, даже после того, как действие уничтожено или после изменения ориентации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...