等待传感器数据 android - 我们总是需要一个新线程吗?

Wait for sensor data android - do we always need a new thread?

我有一个简单的 Android 应用程序,它应该在特定时间间隔从传感器获取多个读数。
我目前有两个线程:

  1. UI 启动序列的线程(通过向工作线程处理程序发送消息),并跟踪其状态(无论我是在进行第一次测量,还是重复测量测量)。

  2. 工作线程,在后台运行并通过主线程处理程序与主线程通信。

我的意图是将所有关于何时进行测量的逻辑保留在主 UI 线程中(那些是简单的数字比较,没有耗时的工作,因此应该适合 UI线程),并设置一个工作线程作为一个线程,它只知道如何响应从传感器读取数据的请求以及读取结果return。

我的问题出在这个工作线程中。它通过消息接收进行测量的请求,并在其 handleMessage 方法中处理此请求:

public boolean handleMessage(Message msg) {
        if (msg.what == StartMeasurementCmd) {
            Log.d(TAG, "Starting measurement");
            // register sensor event listener
            // wait for onSensorChanged
            // unregister sensor event listener
            Log.d(TAG, "Measurement finished");
            // Notify UI thread via uiHandler
            Message newMsg = uiHandler.obtainMessage();
            newMsg.what = DoneMeasurementCmd;
            // add whatever information is needed to the newMsg
            newMsg.setTarget(uiHandler);
            newMsg.sendToTarget();
        }
        return false;
    }

这里 StartMeasurementCmd 和 DoneMeasurementCmd 是简单的常量。

一旦工作线程接收到测量数据的请求,它需要注册一个传感器侦听器(上面第一行注释),但是它需要等待直到读数可用(上面第二行注释)。读取可用后,它将注销侦听器(上面第三行注释),并向 UI 线程发送消息以通知新数据可用。 我可以想到两种方式来填写第二个注释行:

  1. 我可以在另一个线程中进行读取(然后简单地使用 wait() 来同步这个工作线程)——基于这两篇文章:

Android sensor registerListener in a separate thread

A method for waiting for sensor data

  1. 或者,我可以在注册侦听器后简单地放置一个 while 循环,并检查我可以在 onSensorChanged 方法中跳闸的标志。由于工作线程在后台 运行 应该可以阻止它,但我不喜欢我正在使用 "busy" 等待这一事实。

我的问题是 - 有没有办法在同一个工作线程中获取读数,但不执行 "busy" 在 while 循环中等待?还是以上方法中的一种实际上是推荐的方法?

谢谢!

如果我没理解错的话,阻塞工作线程是可以的。然后你不需要一个单独的线程,使侦听器对象成为 monitor(即使用 synchronized 方法)并等待它就足够了。

例如,(粗略勾勒出实际数据的处理方式):

class ListenerMonitor implements WhateverListenerInterface {

    private boolean gotData;
    ... some variable(s) to record the actual data

    public synchronized void onSensorChanged(...) {
        ...
        gotData=true;
        notifyAll();
    }

    public synchronized SuitableReturnType readSensor(...) throws InterruptedException {
        // register sensor event listener
        gotData = false;
        while(!gotData) wait();
        // unregister sensor event listener
        return the data?
    }   
}

并在工作线程中使用它:

...
ListenerMonitor listenerMonitor = new ListenerMonitor(...);
...
public boolean handleMessage(Message msg) {
    if (msg.what == StartMeasurementCmd) {
        Log.d(TAG, "Starting measurement");
        ... = listenerMonitor.readSensor(...);
        Log.d(TAG, "Measurement finished");