Привязать сервис к активности в Android - PullRequest
85 голосов
/ 16 декабря 2009

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

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

Ответы [ 6 ]

147 голосов
/ 16 декабря 2009

"Если вы запустите службу 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(). "

22 голосов
/ 22 августа 2014

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

Клиент

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

    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's of 
    
        public void onServiceDisconnected(ComponentName className) {
            Log.d("ServiceConnection","disconnected");
            myService = null;
        }
    }
    

теперь как вызывать метод который лежит в сервисе

myservice.serviceMethod();

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

10 голосов
/ 09 мая 2011

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

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

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

5 голосов
/ 16 декабря 2009

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

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

Удачи!

0 голосов
/ 02 мая 2015

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

0 голосов
/ 29 апреля 2012

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

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