Android Kotlin将数据从回调类传递到活动

时间:2020-07-29 13:08:07

标签: android kotlin

您好,将数据从另一个类中定义的回调函数传递到您的活动的最佳方法是返回到您的活动。我是android开发的新手,所以很抱歉,如果其中一些是显而易见的。我使用的是Xsens提供的SDK,并提供了一些背景知识,基本上它们提供了传感器,这些传感器通过蓝牙连接到您的设备,然后将数据流回您的设备,例如加速度,方向等。

编写代码的方式是扫描传感器,然后将它们列在我的应用中,然后我可以按每个传感器上的connect键。单击连接的按钮后,便定义了回调类(我的类称为ConnectScannedDevice()

在这个ConnectScannedDevice类中,我重写了以下函数并编写了以下代码

override fun onXsensDotDataChanged(address: String, XsensDotData: XsensDotData) {
    XsensDotData.acc.forEachIndexed() { index, value ->
        Log.d("Sensor Data Acceleration $index", value.toString())
    }

    XsensDotData.dq.forEachIndexed { index, value ->
        Log.d("Sensor Data Orientation $index", value.toString())
    }
}

当我使用以下代码connectedDevice.startMeasuring()开始在设备上进行测量时,就会命中该回调函数。

我的活动中有一个setOnClickListener,然后运行上面的代码以使设备开始测量。

我现在需要做的是将回调函数正在记录的数据传递给logcat并返回到活动。将回调函数记录的数据传递到按下按钮的活动中的最佳方式是什么。

在SDK文档中,它提到了The XsensDotData object has implemented the Parcelable object from Java, so this object can be passed to another class by Broadcast event.

当设备开始测量时,它是恒定的数据流,直到停止测量为止,我需要将所有这些数据传递回活动。我正在尝试将这些数据显示在图形上。

1 个答案:

答案 0 :(得分:0)

以下未经过测试,但概述了创建LiveData流的逻辑。

  • 在您的ConnectScannedDevice类中,添加一个私有MutableLiveData<XsensDotData>属性(您将在数据更改时更新)和一个LiveData<XsensDotData>,并将其公开给ViewModel
    // This is changed internally (never expose a MutableLiveData)
    private var xSensorDataMutableLiveData = MutableLiveData<XsensDotData>()

    // Changed switchMap() to map()
    var xSensorDataLiveData: LiveData<XsensDotData> =
        Transformations.map(xSensorDataMutableLiveData) { data ->
            data
    }

  • 当数据更改时,您想通过xSensorMutableDataLiveData函数来更新onXsensDotDataChanged
    override fun onXsensDotDataChanged(address: String, xSensDotData: XsensDotData) {
        xSensorDataMutableLiveData.value = XsensDotData
    }
  • 现在按如下所示实现您的ViewModel
// Uncomment if you want to use savedState
//class DeviceDataViewModel(private val savedState: SavedStateHandle): ViewModel() {
class DeviceDataViewModel(): ViewModel() {

    // define and initialize a ConnectScannedDevice property
    val connectScannedDevice = ConnecScannedDevice() // or however you initialize it
    // get a reference to its LiveData
    var xSensorDataLiveData = connectScannedDevice.xSensorDataLiveData
}
  • 在活动中像这样抓住ViewModel
    private val deviceDataViewModel by lazy {
        ViewModelProvider(this).get(DeviceDataViewModel::class.java)
    }
  • 注册您的活动以观察LiveData函数中来自ViewModel的{​​{1}}并定义如何响应
onCreate(Bundle?)

注意

Google建议使用存储库模式,这意味着您应该添加一个单例存储库类,该类可以完成 deviceDataViewModel.xSensorDataLiveData.observe( this, Observer { xSensDotData -> xSensDotData.acc.forEachIndexed() { index, value -> Log.d("Sensor Data Acceleration $index", value.toString()) } xSensDotData.dq.forEachIndexed { index, value -> Log.d("Sensor Data Orientation $index", value.toString()) } } ) 当前正在执行的操作。然后,您的ViewModel应该拥有存储库实例,只需获取其ViewModel并将其传递给活动即可。

存储库的工作是从所有来源收集所有数据,并将其传递给各种LiveDataViewModel封装了活动/片段所需的数据,并有助于使数据在配置更改后仍然有效。活动和片段从ViewModel s获取其数据,并将其显示在屏幕上。