Как поймать сбой bindService

У меня есть некоторая передняя служба IntentService, которую можно запустить или остановить. Мне нужно отразить его прогресс (текущее состояние, которое довольно сложно) в действии, если оно видно.

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

Если я делаю bindService, он всегда возвращает true. В случае, если IntentService не запущен, onServiceConnected (а также любые другие обратные вызовы) никогда не вызывается, и моя активность всегда остается в состоянии подготовки.

Единственным рабочим решением, которое я нашел, была статическая переменная в моем классе IntentService, которая указывает, что служба запущена. Но я считаю, что использование такого подхода является плохой практикой, и многие люди предупреждают, что в некоторых случаях он может не работать или быть непредсказуемым.

ВОПРОС. Как разработчики Android ожидают обработки сбоя вызова bindService?

И частный случай: что делать в случае, если мы пытаемся привязаться к службе, которая сейчас не запущена или находится в каком-то промежуточном состоянии (например, завершение работы и т. д.).


person engilyin    schedule 03.07.2018    source источник


Ответы (1)


    private UploadService.Binder mServiceBinder;

    @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            createService();
        }

    private void createService() {
            if (mServiceBinder == null)
                bindService(new Intent(this, UploadService.class),
                        mConnection,
                        Context.BIND_AUTO_CREATE);
        }

private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mServiceBinder = ((UploadService.Binder) service);
            ((UploadService.Binder) service).getService().setCallback(DashFragment.getInstance());
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mServiceBinder = null;
        }
    };
        @Override
        public void onDestroy() {
            super.onDestroy();
            if (mServiceBinder != null) {
                unbindService(mConnection);
                mServiceBinder = null;
            }
        }

Если mServiceBinder не равен нулю, это означает, что ваша служба успешно привязана к активности, иначе вам нужно вызвать метод создания службы.

person Mahavir Jain    schedule 03.07.2018
comment
Неверное решение. Во-первых, это означает, что служба всегда запущена. В моем случае его можно было остановить, запустить и снова остановить в любое время. Использование BIND_AUTO_CREATE не тот случай. И не отвечает на важный вопрос, что произойдет, если по какой-то причине произойдет сбой bindService и onServiceConnected никогда не будет вызван. Это важно для меня, потому что я показываю некоторый подготовительный пользовательский интерфейс, прежде чем служба будет успешно привязана и станет доступно обновление статуса. - person engilyin; 03.07.2018
comment
Возможно, это нехорошее решение, но служба автоматически уничтожается после уничтожения действия, потому что служба связана с действием, и для вашего второго вопроса, когда вы не предоставляете прослушиватель службы или ServiceConnection, чем только onServiceConnected никогда не вызывается. - person Mahavir Jain; 03.07.2018
comment
1) Я предпочитаю вообще не создавать сервис, если он не нужен. Создание его только для привязки действия выглядит не очень хорошо (например, пустая трата ресурсов устройства). 2) Почему вы уверены, что onServiceConnected всегда вызывается? Что делать, если служба не будет создана по какой-либо причине (например, нехватка памяти и т. д.). Знаете ли вы некоторые спецификации или документы, которые гарантируют, что если bindService с BIND_AUTO_CREATE возвращает значение true, то onServiceConnected будет вызываться любым способом? ты - person engilyin; 03.07.2018
comment
Кроме того, есть еще один недостаток подхода BIND_AUTO_CREATE, если ваш IntentService используется в качестве службы переднего плана. Уведомление не исчезает после завершения вашего onHandleIntent. Согласно документам, пока у вас есть хотя бы одно связанное действие, оно будет считаться невыполненным. - person engilyin; 03.07.2018