BluetoothAdapter.getDefaultAdapter() 在不在 Activity 中时抛出 RuntimeException
Posted
技术标签:
【中文标题】BluetoothAdapter.getDefaultAdapter() 在不在 Activity 中时抛出 RuntimeException【英文标题】:BluetoothAdapter.getDefaultAdapter() throwing RuntimeException while not in Activity 【发布时间】:2011-08-20 16:55:56 【问题描述】:当我不在活动中但在TimerTask
(在Service
中创建)中尝试获取默认蓝牙适配器时,使用:
BluetoothAdapter.getDefaultAdapter();
我得到以下异常:
Exception while invoking java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
我的应用程序没有任何活动 - 那么有没有可能让这个适配器远离活动?
【问题讨论】:
查看 android 对此错误的回复:code.google.com/p/android/issues/detail?id=16587 【参考方案1】:这似乎是 Android 中的一个错误,并且在 Android 4.0(冰淇淋三明治)中仍然存在
要解决这个问题并能够从工作线程(例如 AsyncTask)调用 BluetoothAdapter.getDefaultAdapter()
,您所要做的就是在主 UI 线程上调用一次 BluetoothAdapter.getDefaultAdapter()
(例如在您当前活动的 onCreate()
内) )。
RuntimeException 仅在初始化时抛出,BluetoothAdapter.getDefaultAdapter()
仅在您第一次调用时进行初始化。对它的后续调用将成功,即使在后台线程中也是如此。
【讨论】:
错误页面上有任何链接吗?【参考方案2】:在UI
线程中调用BluetoothAdapter.getDefaultAdapter()
有效,但不是很实用。我已经尝试过使用虚假 Activity 的解决方法,但由于我讨厌这样的解决方法,我决定阅读错误消息的真实内容,这只不过是线程没有调用Looper.prepare()
。
因此,在调用 BluetoothAdapter.getDefaultAdapter()
之前调用 Looper.prepare()
应该可以在任何地方解决问题,而不仅仅是在 UI 线程中。
到目前为止对我来说效果很好。
【讨论】:
这似乎是个坏主意,除非你真的打算让你的工作线程成为 Looper。 请注意,您应该检查当前线程是否已经调用了Looper.prepare()
,如下所示:if (Looper.myLooper() == null) Looper.prepare();
否则,您将得到一个RuntimeException
,因为该函数每个线程只能调用一次。 【参考方案3】:
不确定它有多正确,但我添加了这个包装函数:
static boolean m_calledLooperAlready = false;
BluetoothAdapter getDefaultBluetoothAdapter()
if ( !m_calledLooperAlready )
try
android.os.Looper.prepare();
catch ( RuntimeException e ) e.printStackTrace();
m_calledLooperAlready = true;
return BluetoothAdapter.getDefaultAdapter();
...并将所有出现的BluetoothAdapter.getDefaultAdapter()
替换为getDefaultBluetoothAdapter()
。这适用于我:2.2.1、2.3.3、4.0.4、4.3
【讨论】:
【参考方案4】:注意 2.3.x 中存在但在 4.x 中已修复的问题:如果您在主应用程序线程以外的任何线程上调用 BluetoothAdapter.getDefaultAdapter()
,则该线程必须调用 Looper.prepare()
并且随后Looper.loop()
。
如果不这样做,至少会导致我遇到一个问题:accept()
在您第一次尝试连接时会成功,但在随后的尝试中不会成功,即使在 ServerSocket 上使用close()
之后也是如此。
发生这种情况是因为在较早的 BluetoothAdapter 实现中,SDP 条目的清理是通过将消息发布到在调用 getDefaultAdapter()
的线程上创建的处理程序来进行的。
【讨论】:
【参考方案5】:嗨,Kocus,BluetoothAdapter calss
中没有任何名为 getDefault()
的方法。
应该是BluetoothAdapter.getDefaultAdapter();
follow this link for more information.
【讨论】:
您的示例是从Activity
获取BluetoothAdapter
。这不是我想要的。
是的,但我认为 BluetoothAdapter.getDefaultAdapter() 不能从工作线程中调用。它应该来自 UI 线程。
不太明白什么是假Activity。你能提供一些代码吗?以上是关于BluetoothAdapter.getDefaultAdapter() 在不在 Activity 中时抛出 RuntimeException的主要内容,如果未能解决你的问题,请参考以下文章