java - JSON 对象在数组中意外重复

标签 java android json

我正在编写一个记录传感器数据的 Android 应用程序。 试图将这些数据保存到 json 文件中,但 json 数组结果重复了数组中最近一次测量的项目。

private JSONObject mSensorState = new JSONObject();
private JSONArray mSensorBuffArray = new JSONArray();

@Override
public void onSensorChanged(SensorEvent sensorEvent) {
  ...
  mSensorState.put("HR",HR_data);
  mSensorState.put("Step",Step_Data);
  mSensorBuffArray.put(mSensorState);
  Log.d(TAG,"JSON "+ mSensorState.toString());
  Log.d(TAG,"JSON "+ mSensorBuffArray.toString());
}

当前状态“mSensorState”的数据作为 json 对象正确替换。按预期更新

JSON {"HR":"95","Step":"10328"}
JSON {"HR":"96","Step":"10328"}
JSON {"HR":"98","Step":"10328"}

但是数组没有。它显示为最近测量的数组。

JSON [{"HR":"98","Step":"10328"},{"HR":"98","Step":"10328"},{"HR":"98","Step":"10328"},

最佳答案

mSensorState 的失效是有缺陷的。

我猜在 ... 省略的某处,有一个

mSensorState.clear();

但确实应该是

mSensorState = new JSONObject();

这归结为java内存模型,解释的很透彻here on Stackoverflow .那里的评论之一构建了一个体面的类比:

mSensorState 想象成一个气球。然而,在 Java 中,您实际上并没有握住气球,而是握住它的一根绳子。考虑到这一点,让我们看看调用

mSensorBuffArray.put(mSensorState);

首先,将第二个字符串附加到气球并传递给方法调用。在该方法中,mSensorBuffArray 将保留其最新索引中传递的字符串。

一旦使用相同的对象引用再次调用此方法,同样的事情将再次发生并且 mSensorBuffArray 将在两个不同的索引处将两个字符串保存到 相同 气球。因此,通过两个索引都可以看到对该气球所做的更改。

现在,回到

mSensorState = new JSONObject();

这种方法会切断您当前拿着的绳子并将其连接到一个新的气球上。旧气球并没有消失,因为它可能还系着其他绳子。如果没有留下任何字符串,java 最终会在未来的某个时刻破坏气球。


如果适用,JSONObject 也可以通过将其转换为局部变量来绑定(bind)到方法的范围:

public void onSensorChanged(SensorEvent sensorEvent) {
    ...
    JSONObject sensorState = new JSONObject();
    sensorState.put("HR",HR_data);
    sensorState.put("Step",Step_Data);
    mSensorBuffArray.put(sensorState);

如果在其他方法中需要,仍然可以从JSONArray中获取最新的值:(假设它实现了List)

private void internalStuff(/*whatever you need*/) {
    JSONObject sensorState = mSensorBuffArray.get(mSensorBuffArray.size() - 1);

关于java - JSON 对象在数组中意外重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56175567/

相关文章:

java - 使用 Put 方法构建 JSONObject

android - SurfaceView绘制性能

java - 如何在 Android (java) 和 OpenGL ES 2.0 上旋转

python - Pandas:从 JSON 文件检索嵌套数据

java - 如何在 Spring 中使用 Autowiring 的 bean 创建简单工厂模式?

java - 对话框仅在启动时第一次启动?

java - Android 声音媒体播放器 IllegalStateException 并且没有声音

javascript - 将单个对象加载到 sencha touch 中的数据存储中

SQL Server json 被截断(即使使用 NVARCHAR(max) 时也是如此)

java - Hibernate列别名用作实际列名?