Привязать услугу к активности на 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()
. Надеюсь на эту помощь.