我正在开发一个使用设备发现来拾取蓝牙设备的应用程序,特别是该功能使用
Broadcast Receiver
。为了加快速度,我想对该函数进行线程化,使其更快,并且不会滞后于 Kivy 中的 UI,这种情况发生在 MainThread
上。我已经被困在这个问题上有一段时间了,我已经失去了耐心。我对 Python 并不陌生,但这是我的第一个真正的大项目。我不懂 Java,但我可以了解一下。
def example(self, *args):
# [...] code
from android.broadcast import BroadcastReceiver
self.broadcast_receiver = BroadcastReceiver(self.bluetooth_devices, actions=[self.BluetoothDevice.ACTION_FOUND])
self.broadcast_receiver.start()
# [...] more code
self.broadcast_receiver.stop()
def bluetooth_devices(self, context, intent):
device = cast(self.BluetoothDevice, intent.getParcelableExtra(self.BluetoothDevice.EXTRA_DEVICE))
# [...] code that finds detected devices
我知道 BroadcastReceiver 中的回调肯定不是问题,因为当函数
example
不是线程化时它运行良好。然而,一旦我们将它放入线程中,它就会抛出此异常:
JVM exception occurred: Didn't find class
"org.kivy.android.GenericBroadcastReceiver" on path: DexPathList[[directory "."],
nativeLibraryDirectories=[/system/lib64,
/system/lib64]]
java.lang.ClassNotFoundException
根据我的理解,这必定意味着当由 BroadcastReceiver 组成的函数被线程化时,它可能会失去对其启动所需的类的访问权限。如果是这样,有解决办法吗?
我也知道
BroadcastReceiver
有HandlerThread
。
问题依赖于
BroadcastReceiver
,因为它是异步完成的,以某种方式将其放在一个单独的线程中,而不是MainThread
在错误的位置查找类。
我最终所做的是将类构造函数中负责
BroadcastReceiver
的变量初始化为类变量,然后在按下“开始”按钮时初始化 .start()
,并在按下“停止”设备扫描时初始化 .stop()
。然后,作为预防措施,我将 BroadcastReceiver
变量定义为 None 并以与构造函数中相同的方式重新定义它,但在负责停止扫描的函数中。