1

我正在开发一个使用蓝牙发现的应用程序(这里有一些细节)。该应用程序的本质是,我几乎让 BT 始终处于开启状态,并等待某些广播设备更改 BT 名称。电源使用不是问题,因为我的设备正在永久充电。

我发现在某些时候我的应用程序“丢失线程”并且在 BT 上没有发现任何东西,即使 BT 已打开并且范围内有设备。以手动方式,我可以通过在设备上关闭和打开 BT 来解决这个问题 - 很快!它再次起作用。所以我想在代码中做到这一点。我有一个完整的超时计时器,它向处理程序发送一条消息:

        bluetoothHandler = new Handler() {
        @Override
        public void  handleMessage(Message msg) {
            if (!btAdapter.isDiscovering())
            {
                btAdapter.disable();
                btAdapter.enable();
                btAdapter.startDiscovery();
                // some other stuff
            }

好吧,这段代码似乎有时会在“禁用”行出现空指针异常而崩溃

这是ACRA的信息:

"java.lang.NullPointerException
    at android.os.Parcel.readException(Parcel.java:1328)
    at android.os.Parcel.readException(Parcel.java:1276)
    at android.bluetooth.IBluetooth$Stub$Proxy.disable(IBluetooth.java:604)
    at android.bluetooth.BluetoothAdapter.disable(BluetoothAdapter.java:562)
    at com.myapp.stuff.MainActivity$8.handleMessage(MainActivity.java:574)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3687)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
    at dalvik.system.NativeStart.main(Native Method)

正如你所看到的,btAdapter 真的为空是没有意义的,否则我们会在之前的行上崩溃(“if”)——即使假设代码是可重入的,我也不会将 btAdapter 为空我的代码在任何时候 - 我将它设置在 OnCreate 并永远保留它,那么它如何变为空?

我看到几个人发帖说他们得到 NullPointerException 使用启用/禁用代码执行代码 - 并建议使用 Intents 启动/停止蓝牙 - 这不是一个选项 - 没有用户干预 - 用户(如果他们想要这个而不是专门的应用程序才能运行)需要 BT 自动运行(如果没有运行,则需要修复)。

我假设我不能在 NullPointerException 周围进行尝试/捕获(即使它是伪造的) - 有没有人对蓝牙内部有足够的了解来弄清楚为什么禁用会在我身上崩溃?

4

3 回答 3

0

它发生在disable方法内部。可能是文件 BluetoothAdapter.java 的 android 源代码读取,第 562 行帮助您了解可能导致此问题的原因。

于 2012-05-30T20:12:33.177 回答
0

我认为你应该把一个断言作为你的handleMessage函数的第一行,例如assertNotNull(btAdapter)。 这是 Assert 的文档。至少这样你就可以确定 btAdapter 真的不为空。

这并不能真正解决您的问题,但您的问题是一个提醒,断言可能会有所帮助。

于 2012-05-30T21:41:09.253 回答
0

好吧,我真的不明白出了什么问题,但我的修复相当简单和愚蠢:

我没有为 btAdapter 留下一个值,而是每次在使用它之前检查它并尝试/捕获任何异常(尽管我认为这不会捕获真正的空指针)

所以每次我禁用(崩溃)时,我都会这样做

                btAdapter = BluetoothAdapter.getDefaultAdapter();
                if (null == btAdapter)
                {
                    Log.e(LOG_TAG,"Bluetooth adapter is NULL!!!");
                    return;
                }
                try {
                    btAdapter.disable();
                }
                catch (Exception e) {
                    //don't do anything
                }
于 2012-06-18T10:26:36.383 回答