onServiceConnected никогда не вызывается после метода bindService - PullRequest
31 голосов
/ 21 марта 2010

У меня есть особая ситуация: служба, запущенная приемником вещания, запускает действие.Я хочу, чтобы эта деятельность могла общаться со службой.Я решил использовать AIDL, чтобы сделать это возможным.Кажется, все работает хорошо, за исключением bindService() метода, вызванного в onCreate() действия.Фактически, bindService () генерирует исключение нулевого указателя, потому что onServiceConnected() никогда не вызывается, в то время как onBind() метод службы.В любом случае bindService() возвращает истину.Служба, очевидно, активна, потому что она начинает деятельность.Я знаю, что вызов действия из службы может звучать странно, но, к сожалению, это единственный способ иметь распознавание речи в службе.

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

Ответы [ 10 ]

45 голосов
/ 06 мая 2011

Я только что испытал другую версию этой проблемы с тем же симптомом 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, по-видимому, решает проблему, только если указанная служба находится в том же пакете, что и манифест; То есть, если ваше приложение находится в пакете a.b.c, и именно здесь находится AndroidManifest.xml, тогда «YourService» также должен быть в пакете a.b.c. (вручную скопировать из другой библиотеки, если необходимо), иначе тег <service..> может / будет проигнорирован и onServiceConnected(...) по-прежнему не будет вызываться.

Это имело место для моего проекта, хотя я использовал в своем коде подходящую инструкцию импорта для Сервиса. В Eclipse не было ошибок, поэтому импорт правильно идентифицировал класс из другой библиотеки в рабочей области Eclipse.

НТН

41 голосов
/ 20 мая 2010

После нескольких часов попыток выяснить это, проблема в том, что примеры, которые показывают создание службы, не включают метод onBind, или у них есть следующий пример кода, или он генерирует это для вас: 1001 *

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;
  }
}
26 голосов
/ 28 января 2013

Событие 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 .

13 голосов
/ 21 марта 2010

Я не могу составить точную проблему из вашего описания, поэтому я собираюсь угадать здесь!

Как можно bindService() бросить NullPointerException? Единственный способ, которым это может (/ должно) случиться, - это когда вы не используете Service или ServiceConnection слушатель.

bindService() не может бросить NullPointerException , потому что onServiceConnected() не вызывается. Звонок на onServiceConnected() является продуктом bindService().

Итак, я полагаю, что вы вызываете метод AIDL до того, как Service действительно соединится?

8 голосов
/ 10 мая 2012

Еще одна вещь: если вы вызываете метод bindservice внутри метода oncreate, то onserviceconnected вызывается после завершения метода oncreate.

Таким образом, любые ссылки на функции интерфейса до окончания oncreate (или до вызова onserviceconnected) показывают исключение нулевого указателя.

5 голосов
/ 22 февраля 2013

Еще одна причина первоначального вопроса может заключаться в том, что служба еще не запущена, и вы передаете 0 в качестве флага bindService. Вот так:

bindService(intent, serviceConnection, 0);

Когда то, что вы ищете, будет:

bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
1 голос
/ 22 августа 2013

Может быть другое объяснение, не очень частая ситуация, но мне удалось войти в нее и потерять 2 часа, чтобы ее решить.

Итак, я хотел повторно использовать пакет из намерения, полученного методом onBind. Но я пошел на ленивую версию и изменил класс намерения. Очевидно, это приводит к тому, что onServiceConnected не вызывается. Возможно, потому что система сохраняет ссылку на намерение и использует ее при вызове onServiceConnected.

В заключение не меняйте намерения, которые вы получаете в onBind.

0 голосов
/ 01 февраля 2019

Если кто-то все еще ищет ответ после попытки всех остальных, то это может помочь .. onServiceConnected() не вызывается сразу после bindService(...). это займет несколько секунд. Поэтому, если вы получаете какое-то значение из onServiceConnected() и вам нужно использовать его где-то еще в onCreate или onStart, оно выдаст исключение NullPointerException из-за задержки . Поэтому, если вы можете сместить строку кода, для которой нужно значение, с onCreate или onStart, внутри onServiceConnected(){......}, ниже строки объявления нужного вам значения, это может сработать.

0 голосов
/ 26 января 2019

Вы должны дождаться завершения метода onCreate ().Пример: установите сервис покупки в кнопке:

Button button_useservice=findViewById(R.id.button_useservice);
            button_useservice.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    UsinService();
                }
            });
0 голосов
/ 17 февраля 2014

Я звонил Бинду с пустым Намерением - getContext().bindService(new Intent(), mConnection, Context.BIND_AUTO_CREATE). Я должен сделать намерение более конкретным, чтобы указать, к какой услуге я хочу привязаться. Это, очевидно, ошибка кода, но, к сожалению, вывод Logcat был недостаточно ясен.

...