Когда следует использовать unbindService (), и как я должен использовать его правильно, чтобы отвязать от удаленной службы, использующей интерфейс AIDL?

Я пишу простой музыкальный плеер, и я создал службу воспроизведения, которая реализует интерфейс AIDL для привязки к клиентам, один простой браузер треков, а другой – еще более простую деятельность игрока. Служба управляет объектом MediaPlayer, в то время как два действия используют ServiceConnections для получения соединений с сервисом.

Это включено в методы onStart () для обоих видов деятельности:

@Override public void onStart() { super.onStart(); Intent i = new Intent(this, PureService.class); startService(i); bindService(i, mConnection, 0); } 

Я сделал это, чтобы служба не сразу остановилась на развязывании. Конечно, на самом деле это не проблема, потому что моя деятельность вообще не отказывается от службы. В любое время, когда мое приложение получает unbindService в любом из этих действий, unbindService бросает IllegalArgumentException каждый раз, без исключения (hehe).

В методах onStop:

 @Override public void onStop() { super.onStop(); if (mBound) { try { unbindService(mConnection); } catch (java.lang.IllegalArgumentException e) { //Print to log or make toast that it failed } } mBound = false; } 

Что мне интересно, так это:

  • Должен ли я вызвать unbindService () в методе onStop ()? Или вообще?
  • Правильно ли я это называю?
  • Есть ли что-то особенное в том, как я начинаю / связываю службу, о которой я должен знать?
  • Я делаю что-то совершенно, совершенно неправильно? Я новичок в программировании на Android, так что это, конечно, не может быть и речи.

Заранее спасибо.

EDIT: здесь переопределяются ServiceConnection

 public void onServiceConnected(ComponentName className, IBinder service) { mBound = true; mService = IPureService.Stub.asInterface(service); } public void onServiceDisconnected(ComponentName arg0) { mBound = false; } 

В игре есть еще один код, но он не связан с самой привязкой.

Во-первых, если вам действительно не нужно звонить в эту службу через процессы (то есть из других .apks или вы используете android: процесс по какой-то причине разбивает ваш собственный .apk на несколько процессов), то я действительно рекомендую просто Отказа от использования помощи. Это сложнее без выигрыша. В «Сервисной документации» в «Служебной документации» показано, как это сделать: http://developer.android.com/reference/android/app/Service.html

Во-вторых, выполнение привязки в то же время, что и начало, является ярким свидетельством некоторого базового недостатка в дизайне. Запуск службы и привязка к сервису семантически очень различны, поэтому это будет сделано в разных местах на основе этих разных семантик. То есть, если оба они даже сделаны вообще … на самом деле это необычная ситуация, когда вы используете как start, так и bind с одной и той же службой.

В реализации класса для выполнения воспроизведения музыки он будет использовать старт, когда он активно выполняет воспроизведение (поэтому его процесс не будет убит системой, когда пользователь больше не будет активно взаимодействовать с пользовательским интерфейсом приложения). Запуск службы, когда пользователь входит в пользовательский интерфейс, может вызвать боль, потому что теперь состояние запуска / остановки службы четко не определено – его можно запустить либо из-за того, что он выполняет воспроизведение, либо из-за того, что пользователь попал в Пользовательский интерфейс приложения, и теперь, когда настало подходящее время, чтобы остановить его? Это будет хлопотно.

Теперь, когда вам нужно отвязать – вам просто нужно убедиться, что вы всегда сопоставляете unbindService () с предыдущим bindService (). Из ваших фрагментов кода кажется, что вы это делаете, но в нем есть странные вещи, например, mBound никогда не устанавливается. На самом деле, если вы постоянно привязываетесь к onStart () и не привязываетесь к onStop (), вам никогда не понадобится mBound, чтобы решить, следует ли отменить привязку, потому что onStop () всегда вызывается после onStart ().

Итак, с кодом, который вы здесь приводите, похоже, что проблема не возникает. Однако, если вы получаете исключения, очевидно, что это может быть в другом месте вашего приложения. Чтобы уменьшить проблему, вы можете использовать этот флаг, когда вы вызываете bindService (), чтобы получить дополнительную информацию в журнале, когда произошел сбой: http://developer.android.com/reference/android/content/Context.html# BIND_DEBUG_UNBIND

Несколько баллов:

  1. Верните START_STICKY в onStartCommand, если вы хотите, чтобы ваша служба работала дольше, чем связанные действия.
  2. UnbindService () в onStop в порядке: это то, где я называю это в нескольких приложениях, и я никогда не видел эту конкретную ошибку. Я ожидаю, что у вас есть еще mConnection проблема с вашим ServiceConnection: покажите код для вашего объекта mConnection и мы можем, возможно, выяснить, что с ним не так.

У меня тоже была эта странная ошибка. Затем я попытался выполнить привязку к службе в onResume (), а не в onStart () в Activity, и voila, никаких исключений! Я все еще немного не знаю, почему это работает. Если бы кто-то мог объяснить, я был бы одним счастливым кодером. 🙂