Подтвердить что ты не робот

OnServiceConnected никогда не вызывается после метода bindService

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

НТН

Ответ 3

По прошествии нескольких часов и часов, чтобы понять это, проблема заключается в том, что примеры, показывающие создание службы, не включают метод 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;
  }
}

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

bindService(intent, serviceConnection, 0);

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

bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

Ответ 7

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

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

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

Ответ 8

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

Ответ 9

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

Button button_useservice=findViewById(R.id.button_useservice);
            button_useservice.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    UsinService();
                }
            });

Ответ 10

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