onServiceConnected никогда не вызывается после метода bindService
У меня особая ситуация: служба, запущенная приемником вещания, запускает действие. Я хочу, чтобы эта деятельность могла общаться со службой. Я решил использовать AIDL, чтобы сделать это возможным. Кажется, все работает хорошо, за исключением bindService()
метод вызывается в onCreate()
деятельности. bindService() фактически выдает исключение нулевого указателя, потому что onServiceConnected()
никогда не вызывается onBind()
Способ обслуживания есть. Тем не мение bindService()
возвращает истину. Сервис, очевидно, активен, потому что запускает активность. Я знаю, что вызов деятельности из службы может показаться странным, но, к сожалению, это единственный способ распознавания речи в службе.
заранее спасибо
10 ответов
Я не могу составить точную проблему из вашего описания, поэтому я собираюсь угадать здесь!
Как может bindService()
бросить NullPointerException
? Единственный способ, которым это могло (/ должно) случиться, - это когда вы не предоставляете Service
или ServiceConnection
слушатель.
bindService()
не могу бросить NullPointerException
так как onServiceConnected()
не называется. Призыв к onServiceConnected()
является продуктом bindService()
,
Так что я думаю, что вы звоните AIDL
метод, перед Service
на самом деле связаны?
Я только что испытал другую версию этой проблемы, с тем же симптомом onServiceConnected(...)
не вызывается. Причина была другой в моем случае.
Вы должны убедиться в том, что в теге AndroidManifest.xml есть тег службы в теге приложения - для меня это было корнем проблемы.
<application android:name=".YourAppTitle" android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Main" android:label="@string/app_name">
</activity>
<service android:name="YourService" />
</application>
Есть дополнительная сложность, если вы используете отдельную библиотеку Android в Eclipse - добавление этого тега Service, по-видимому, решает проблему, только если указанная служба находится в том же пакете, что и манифест; то есть, если ваше приложение находится в пакете abc, и именно здесь находится AndroidManifest.xml, то "YourService" также должен быть в пакете abc (вручную скопирован из другой библиотеки, если это необходимо), иначе <service..>
тег может / будет игнорироваться и onServiceConnected(...)
все равно не будет звонить.
Это имело место для моего проекта, хотя я использовал подходящий оператор импорта для Сервиса в своем коде. В Eclipse не было ошибок, поэтому импорт правильно идентифицировал класс из другой библиотеки в рабочей области Eclipse.
НТН
После нескольких часов попыток выяснить это, проблема в том, что примеры, показывающие создание службы, не включают метод onBind, или они имеют следующий пример кода, или он генерирует это для вас:
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
Это приводит к сбою метода onServiceConnected или его фактическому выполнению. Исправление очень простое, а именно:
public IBinder onBind(Intent intent) {
return mBinder;
}
Где вы можете создать простое связующее, например, следующее, чтобы вернуть:
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
public ConferenceService getService() {
return ConferenceService.this;
}
}
Событие onServiceConnected никогда не вызывалось в моем приложении.
Проблема заключалась в том, что у меня было имя службы, определенное в моем манифесте приложения как:
<service android:name="MyService" android:enabled="true"></service>
Как только я изменил его на полное имя класса, это сработало:
<service android:name="com.example.MyService" android:enabled="true"></service>
Обновление: Вы также можете использовать относительное имя класса:
<service android:name=".MyService" android:enabled="true"></service>
Укажите имя класса, используя его полный com.example.MyServiceClass вместо только MyServiceClass.
Еще одна вещь, что если вы звоните bindservice
метод внутри oncreate
метод, то onserviceconnected
называется после oncreate
Метод закончен.
Таким образом, любые ссылки на функции интерфейса до oncreate
заканчивается (или до onserviceconnected
) показывает исключение нулевого указателя.
Еще одна причина первоначального вопроса может заключаться в том, что служба еще не запущена, и вы передаете 0 в качестве флага bindService. Вот так:
bindService(intent, serviceConnection, 0);
Когда то, что вы ищете, будет:
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
Если кто-то все еще ищет ответ после попытки всех остальных, то это может помочь.. onServiceConnected()
не вызывается сразу после bindService(...)
, это займет несколько секунд. Так что, если вы получаете какое-то значение от onServiceConnected()
и вы должны использовать его где-то еще в onCreate
или же onStart
это вызовет исключение NullPointerException из-за задержки. Так что, если вы можете сдвинуть ту строку кода, которая нуждается в значении от onCreate
или же onStart
внутри onServiceConnected(){......}
ниже строки объявления значения, которое вам нужно, это может сработать.
Я просто потратил на это много времени, и, поскольку в моем случае это не было ни одного из приведенных выше ответов, я просто изложу другой возможный сценарий:
Это случилось со мной, когда я использовал kotlin.coroutines.Deferred
объект, представляющий мою связанную службу, и я заблокировал поток, который onServiceConnected
должен быть вызван, когда я позвонил await()
на этом объекте.
Итак, в основном - не блокируйте основной поток, ожидая onServiceConnected
называться, иначе не назовется...
Я тоже столкнулся с той же проблемой. И через несколько минут я обнаружил, что в моем коде нет никаких проблем. Проблема заключалась в файле манифеста. Раньше я декларировал сервис только по его названию.
<service android:name=".MyBoundService"/>
Измените его на полное имя с именем пакета
<service android:name="com.pb.servicedemo.MyBoundService"/>
Таким образом, вы сможете увидеть, что ваш сервис привязан к активности.
Может быть и другое объяснение, не очень частая ситуация, но мне удалось в нее разобраться и потерять 2 часа на ее решение.
Поэтому я хотел повторно использовать пакет из намерения, полученного методом onBind. Но я пошел на ленивую версию и изменил класс намерения. Очевидно это заставляет onServiceConnected не вызываться. Возможно, потому что система сохраняет ссылку на намерение и использует ее при вызове onServiceConnected.
В заключение не меняйте намерения, которые вы получаете в onBind.
Я звонил Бинд с пустым намерением - getContext().bindService(new Intent(), mConnection, Context.BIND_AUTO_CREATE)
, Я должен сделать намерение более конкретным, чтобы указать, к какой услуге я хочу привязаться. Это, очевидно, ошибка кода, но, к сожалению, вывод Logcat был недостаточно ясен.
Вы должны дождаться завершения метода onCreate(). Пример: установите сервис покупки в кнопке:
Button button_useservice=findViewById(R.id.button_useservice);
button_useservice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
UsinService();
}
});