Привязать сервис к активности в Android

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

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


person aspartame    schedule 16.12.2009    source источник


Ответы (6)


"Если вы запустите службу 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. Если ни одна из этих ситуаций не выполняется, вызывается onDestroy() метод Службы, и служба фактически прекращает работу. Вся очистка (остановка потоков, отмена регистрации получателей) должна быть завершена после возврата из onDestroy(). "

person Schildmeijer    schedule 16.12.2009
comment
небольшая путаница: правда ли, что если активность будет уничтожена, служба также будет уничтожена? Или эта служба не уничтожается только в том случае, если я использую свой собственный AIDL? Я спрашиваю, потому что, когда я использую startService (особенно на IntentService), служба останавливается, когда ее работа завершена, а не когда действие умирает. Так правда ли, что если действие умирает, то и связанная (исключительно) служба также умирает? - person Katedral Pillon; 06.08.2015
comment
если вы используете простой сервер, вызывая startService, тогда служба не остановится, пока вы не вызовете stopSelf () или stopService (). А затем, если вы используете bindService, тогда да, служба умрет, если все подключенные / привязанные компоненты будут уничтожены. - person Asif Mushtaq; 02.07.2017
comment
@UnKnown Если служба запускается с помощью startService (), то, независимо от того, привязываете ли вы ее или отменяете привязку, она будет продолжать работать и может быть уничтожена только вызовом stopService () или stopSelf (). Таким образом, даже если действие, связанное с сервисом, будет уничтожено, сервис не будет уничтожен. - person CopsOnRoad; 04.02.2018
comment
Не могли бы вы помочь мне с этим вопросом https://stackoverflow.com/questions/51508046/binding-a-jobintentservice-to-a-activity - person Rajesh K; 25.07.2018

Прежде всего, две вещи, которые нам нужно понять.

Клиент

  • он делает запрос к определенному серверу

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

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

Сервер

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

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

  • сервер отправляет ответ с помощью объекта IBind. поэтому объект 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's of 
    
        public void onServiceDisconnected(ComponentName className) {
            Log.d("ServiceConnection","disconnected");
            myService = null;
        }
    }
    

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

myservice.serviceMethod();

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

person Hardik Gajera    schedule 22.08.2014

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

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

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

person M.Hefny    schedule 09.05.2011

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

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

Удачи!

person vrutberg    schedule 16.12.2009

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

person German    schedule 02.05.2015

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

person Mira Febriani    schedule 29.04.2012
comment
Вам придется переопределить функцию и удалить вызов по умолчанию суперкласса onDestroy (), если ваша IDE автоматически создает его. но зачем вам это делать? - person Riptyde4; 08.01.2015