当我用系统服务注册回调对象时,我想知道发生了什么。在我的情况下,我在连接到BLE设备时注册了BluetoothGattCallback。我发现当我尝试在我的一个回调方法中更新TextView时,我的应用程序的主线程上没有发生回调。
我的理解是框架调用的生命周期和其他方法以某种方式(可能通过Application中的ipc处理程序)添加到我的主线程Looper的MessageQueue(事件循环)中,并在Looper勾选特定内容时在我的主线程上执行迭代循环中的消息。
那么当调用我的GATT回调方法时会发生什么?当他们在不同的线程上运行时会强制并发吗?是否涉及一些同步机制?主线程的事件循环是否被绕过?或者我对基本概念有完全的误解?
答案 0 :(得分:0)
您可以在虚拟机中运行多个线程。所有Android生命周期方法都在主(UI)线程上运行,许多系统回调也在主线程上运行。但是,一些回调将在其他线程上运行,要么是因为你要求这种行为,要么是因为回调是这样编程的。
由于您提到的回调正在其他线程(而不是主(UI)线程)上运行,因此您必须确保在回调方法中执行的代码中不对UI执行任何操作。您可以通过在Runnable
中包装任何内容并通过调用runOnUiThread()
在主(UI)线程上运行它来轻松解决此问题。
关于并发性,这取决于您的应用程序架构。如果在回调方法中运行的代码正在访问您在主(UI)线程上运行的代码中访问的数据,那么您可以同时访问该数据,并且需要提供任何必要的同步(如果需要)以避免出现问题
您询问主线程的事件循环。如果这些回调没有在主(UI)线程上运行,那么他们就不会与主要的thead及其事件循环有任何关系。
答案 1 :(得分:0)
感谢您的回答。到目前为止,我认为默认情况下,应用只存在一个线程。我在Google Group上找到了Dianne Hackborn的this clarification:
具体来说,每个进程都有一个"绑定线程"坐在那里等待来自其他进程的传入的IPC。当IPC被分派到您的进程时,其中一个线程从池中出来进行处理。这些可能直接通过您从服务发布到另一个流程的IBinder,半直接通过从另一个流程到您已发布的ContentProvider的调用,或间接来自系统在应用程序流程中的各种IPC进行告诉发起活动,接受意图等。
Dianne Hackborn
Android框架工程师