35

我有一个特殊的情况:广播接收器启动的服务启动了一个活动。我想让这个活动能够与服务进行通信。我选择使用 AIDL 来实现它。bindService()除了调用活动的方法外,一切似乎都很好onCreate()。实际上,bindService() 会抛出一个空指针异常,因为在服务的方法onServiceConnected()is 时从未调用过onBind()。无论如何bindService()返回true。该服务显然是活动的,因为它启动了活动。我知道从服务调用活动听起来很奇怪,但不幸的是,这是在服务中进行语音识别的唯一方法。

提前致谢

4

12 回答 12

53

经过数小时试图弄清楚这一点,问题在于显示服务创建的示例不包含 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;
  }
}
于 2010-05-20T06:55:15.327 回答
52

我刚刚经历了这个问题的另一个版本,同样的症状是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>

如果您在 Eclipse 中使用单独的 Android 库,则会有一个额外的复杂性 - 如果引用的服务与清单位于同一包中,添加此服务标记似乎只能解决问题;即,如果您的应用在包 abc 中并且这是 AndroidManifest.xml 所在的位置,那么“YourService”也必须在包 abc 中(如有必要,从另一个库手动复制),否则该<service..>标签可能/将被忽略,onServiceConnected(...)但仍将获得“不叫。

即使我在代码中为服务使用了合适的导入语句,我的项目也是如此。Eclipse 没有显示错误,因此导入正确地识别了 Eclipse 工作区中另一个库中的类。

高温高压

于 2011-05-06T01:49:03.183 回答
26

我的应用程序中从未调用过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指定类名。

于 2013-01-28T12:58:40.523 回答
14

我无法根据您的描述弥补确切的问题,所以我要在这里猜测!

怎么能bindService()NullPointerException?这可能(/应该)发生的唯一方法是当您不提供 aServiceServiceConnection侦听器时。

bindService()不能抛出 aNullPointerException 因为 onServiceConnected()没有被调用。调用onServiceConnected()是 的产物bindService()

所以我猜你是在实际绑定AIDL之前调用一个方法?Service

于 2010-03-21T13:07:44.183 回答
10

另一件事是,如果您在bindservice方法内部调用方法,oncreateonserviceconnected在方法完成后调用oncreate

oncreate因此,在结束之前(或在调用之前)对接口函数的任何引用onserviceconnected都会显示空指针异常。

于 2012-05-10T05:28:25.290 回答
5

原始问题的另一个原因可能是该服务尚未运行,并且您将 0 作为标志传递给 bindService。像这样:

bindService(intent, serviceConnection, 0);

当您正在寻找的是:

bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
于 2013-02-22T08:19:41.743 回答
2

如果有人在尝试了所有其他人之后仍在寻找答案,那么这可能会有所帮助.. 之后不会立即onServiceConnected() 调用。这需要几秒钟。因此,如果您从 接收到一些值并且您必须在其他地方使用它,否则它将由于延迟而抛出 NullPointerException 。因此,如果您可以将需要该值的代码行从or , inside移到您需要的值的声明行下方,那么它可能会起作用。bindService(...)onServiceConnected()onCreateonStartonCreateonStartonServiceConnected(){......}

于 2019-01-31T22:25:45.600 回答
1

可能还有另一种解释,不是很常见的情况,但我设法进入它并浪费了 2 个小时来解决它。

所以我所做的是我想重用来自 onBind 方法接收到的意图的包。但我选择了懒惰的版本并改变了意图的类。显然这会导致 onServiceConnected 没有被调用。可能是因为系统保留了对意图的引用,并在调用 onServiceConnected 时使用它。

总之,不要更改您在 onBind 中收到的意图。

于 2013-08-22T11:25:26.030 回答
1

我也遇到了同样的问题。几分钟后,我发现我的代码完全没有问题。这是有问题的清单文件。早些时候我只用它的名字来声明服务。

<service android:name=".MyBoundService"/>

将其更改为带有包名的全名

<service android:name="com.pb.servicedemo.MyBoundService"/>

这样,您将能够看到您的服务绑定到活动。

于 2020-08-13T16:00:46.057 回答
0

我用一个空的 Intent 调用 bind - getContext().bindService(new Intent(), mConnection, Context.BIND_AUTO_CREATE)。我必须使意图更具体,以指示我要绑定到哪个服务。这显然是代码错误,但遗憾的是 Logcat 输出不够清晰。

于 2014-02-17T13:07:41.080 回答
0

您必须等待完成 onCreate() 方法。示例:在按钮中设置您的购买服务:

Button button_useservice=findViewById(R.id.button_useservice);
            button_useservice.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    UsinService();
                }
            });
于 2019-01-26T05:35:23.157 回答
0

我只是在这个问题上花了很多时间,因为就我而言,上述答案都不是,所以我将列出另一种可能的情况:

当我使用一个kotlin.coroutines.Deferred对象来表示我的绑定服务时,这发生在我身上,当我调用这个对象时,我阻塞了onServiceConnected应该调用的线程。await()

所以基本上 - 不要阻塞等待onServiceConnected被调用的主线程,否则它将无法被调用......

于 2020-04-16T23:05:28.683 回答