Привязать услугу к активности на Android

Я пытаюсь написать простой медиаплеер, который воспроизводит потоковое аудио, используя RTSP. У меня есть GUI-активность и служба, которая выполняет воспроизведение. Мой вопрос заключается в том, как наилучшим образом общаться между активностью и службой (например, обновлять gui на основе состояния плеера).

Я знаю, что я могу привязать службу к активности, используя onBind(), но если я правильно пойму, это остановит службу, если действие будет убито. Я хочу продолжить воспроизведение, даже если пользователь выходит из этой операции. Есть ли какой-либо стандартный или предпочтительный способ решения этой проблемы?

Ответ 1

"Если вы запустите службу android с помощью startService(..), эта служба будет работать до тех пор, пока вы явно не вызовете stopService(..). Существует две причины, по которым система может управлять сервисом. Если кто-то звонит Context.startService(), тогда система будет получать сервис (создавая его и вызывая его метод onCreate(), если это необходимо), а затем вызывает его метод onStartCommand(Intent, int, int) с аргументами, предоставленными клиентом. Служба продолжит работу до тех пор, пока не будут вызываться Context.stopService() или stopSelf(). Обратите внимание, что несколько вызовов Context.startService() не вложены (хотя они приводят к нескольким соответствующим вызовам на onStartCommand()), поэтому независимо от того, сколько раз он запускается, служба будет остановлена ​​после вызова Context.stopService() или stopSelf(); однако службы могут использовать свой метод stopSelf(int), чтобы гарантировать, что служба не остановлена ​​до тех пор, пока не будут обработаны начатые намерения.

Клиенты также могут использовать Context.bindService() для получения постоянного подключения к службе. Это также создает службу, если она еще не запущена (вызов onCreate() при этом), но не вызывает onStartCommand(). Клиент получит объект IBinder, который служба возвращает из своего метода onBind(Intent), позволяя клиенту выполнить обратные вызовы к службе. Служба будет работать до тех пор, пока установлено соединение (независимо от того, сохраняет ли клиент ссылку на Сервис IBinder). Обычно возвращаемый IBinder представляет собой сложный интерфейс, написанный в AIDL.

Служба может быть запущена и связана с ней. В таком случае система будет поддерживать работу службы до тех пор, пока она запущена или есть одно или несколько подключений к ней с флагом Context.BIND_AUTO_CREATE. Когда ни одна из этих ситуаций не выполняется, вызывается метод Service onDestroy() и служба фактически прекращается. Вся очистка (остановка нитей, незарегистрированные приемники) должна быть завершена после возврата из onDestroy().

Ответ 2

Прежде всего, нам нужно понять, что нужно

Client

  • он запрашивает конкретный сервер

    bindService(new 
        Intent("com.android.vending.billing.InAppBillingService.BIND"),
            mServiceConn, Context.BIND_AUTO_CREATE);`
    

здесь mServiceConn является экземпляром класса ServiceConnection (встроенным), это фактически интерфейс, который нам нужно реализовать с помощью двух (1-й для подключенного к сети и 2-го сетевого не подключенного) метода для мониторинга состояния сетевого подключения.

Сервер

  • Он обрабатывает запрос клиента и делает копию своей собственной, которая является частной только для клиентов, которые отправляют запрос, и эта реплика сервера выполняется в разных потоках.

Теперь на стороне клиента, как получить доступ ко всему методу сервера?

  • Ответ на отправку сервера с IBind Object.so Объектом IBind является наш обработчик, который получает доступ ко всему методу службы с помощью (.) оператора.

    MyService myService;
    public ServiceConnection myConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder binder) {
            Log.d("ServiceConnection","connected");
            myService = binder;
        }
        //binder comes from server to communicate with method of 
    
        public void onServiceDisconnected(ComponentName className) {
            Log.d("ServiceConnection","disconnected");
            myService = null;
        }
    }
    

теперь как вызвать метод, который находится в сервисе

myservice.serviceMethod();

здесь myService - объект, а serviceMethode - метод в обслуживании. И таким образом устанавливается связь между клиентом и сервером.

Ответ 3

Я попытался позвонить

startService(oIntent);
bindService(oIntent, mConnection, Context.BIND_AUTO_CREATE);

следовательно, и я мог бы создать липкую услугу и привязать ее. Подробный учебник для Пример Bound Service.

Ответ 4

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

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

Удачи!

Ответ 5

Это предвзятый ответ, но я написал библиотеку, которая может упростить использование служб Android, если они выполняются локально в том же процессе, что и приложение: https://github.com/germnix/acacia

В основном вы определяете интерфейс, аннотированный с помощью @Service и его реализующим классом, и библиотека создает и связывает эту службу, обрабатывает соединение и рабочий поток фона:

@Service(ServiceImpl.class)
public interface MyService {
    void doProcessing(Foo aComplexParam);
}

public class ServiceImpl implements MyService {
    // your implementation
}

MyService service = Acacia.createService(context, MyService.class);
service.doProcessing(foo);

<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    ...
    <service android:name="com.gmr.acacia.AcaciaService"/>
    ...
</application>

Вы можете получить экземпляр связанного с ним android.app.Service, чтобы скрыть/показать постоянные уведомления, использовать свой собственный android.app.Service и вручную обрабатывать потоки, если хотите.

Ответ 6

Если пользователь отступит, будет вызван метод onDestroy(). Этот метод должен остановить любую службу, которая используется в приложении. Поэтому, если вы хотите продолжить службу, даже если пользователь отступает от приложения, просто удалите onDestroy(). Надеюсь на эту помощь.