Realm在Android中像LinkedList一样使用

时间:2016-03-23 22:12:15

标签: android realm mpandroidchart

我有一个传感器值的Realm数据库,其中包含以下构造函数:

public DataEntry(float x, float y, float z, long timestamp, int xIndex, String xValue) {
    this.x = x;
    this.y = y;
    this.z = z;
    this.xIndex = xIndex;
    this.timestamp = timestamp;
    this.xValue = xValue;
}

我希望这个数据库是100分的固定大小。我有一个在LinkedList方法中工作,我删除第一个条目并添加一个到最终导致固定大小然后我使用MPChartLib绘图。这就是我想用Realm数据库模仿的东西。

我的方法是首先使用以下代码删除第一个条目:

private void removeFirst(){
    RealmResults<DataEntry> result1 = mRealm.where(DataEntry.class).findAll();


    mRealm.beginTransaction();
    Log.i(TAG, "remove the first element of the database ");
    DataEntry first =result1.first();
    first.removeFromRealm();
    Log.i(TAG, "shift the indexes of the database by one  " + result1.size());

        for (int i = 0; i < result1.size(); i++) {
            DataEntry u = result1.get(i);
            int index = u.getxIndex();
            u.setxIndex(index - 1);
            String xValue = "" +index;
            u.setxValue(xValue);
       }
    mRealm.commitTransaction();
}

然后我从获取的数据中添加一个新的数据点

@Subscribe
public void onSensorUpdatedEvent(SensorUpdatedEvent event) {
    if (event.getSensor().getId() == this.sensor.getId()) {
//       Log.i(TAG, "remove the first element of the database ");
        removeFirst();
        mRealm.beginTransaction();


        DataEntry entry = mRealm.createObject(DataEntry.class);
  //      Log.i(TAG, "in database update event with index =  " + nextIndex);
        entry.setxIndex(nextIndex);
        entry.setxValue("" + nextIndex);
        nextIndex++;
        entry.setAndroidDevice(mAndroidId);
        entry.setTimestamp(event.getDataPoint().getTimestamp());
        currT.setText(precsion.format(event.getDataPoint().getTimestamp()));
        if (event.getDataPoint().getValues().length > 0) {
            entry.setX(event.getDataPoint().getValues()[0]);
            currX.setText(precsion.format(event.getDataPoint().getValues()[0]));
        } else {
            entry.setX(0.0f);
        }

        if (event.getDataPoint().getValues().length > 1) {
            entry.setY(event.getDataPoint().getValues()[1]);
            currY.setText(precsion.format(event.getDataPoint().getValues()[1]));
        } else {
            entry.setY(0.0f);
        }

        if (event.getDataPoint().getValues().length > 2) {
            entry.setZ(event.getDataPoint().getValues()[2]);
            currZ.setText(precsion.format(event.getDataPoint().getValues()[2]));
        } else {
            entry.setZ(0.0f);
        }
        deltaT.setText(precsion.format((event.getDataPoint().getTimestamp() - lastT) / scaleT));
        lastT = event.getDataPoint().getTimestamp();
        entry.setAccuracy(event.getDataPoint().getAccuracy());
        mRealm.commitTransaction();

    }
}

MPChartLib使用xIndex沿x轴建立位置,因此我将这些值更改为removeFirst类的一部分。我在MpChartLib中的结果不能给我想要的结果。我可能在其应用之外使用它,或者我可能没有以正确的方式使用Realm。

什么样的理由是从100个空白数据库条目开始然后一次填充一个,直到我达到100然后&#34; shift&#34;条目使得条目1变为条目0,条目99变为98并且我用新数据更新条目99。

虽然我认为这可能会起作用,但转移100个固定数据库点的值似乎效率很低。

我宁愿删除第一个并在末尾添加一个新的,就像我可以使用LinkedList一样。

有点迷失如何继续。非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

RealmQuery.findAll()无法为您提供稳定的结果订单。您需要根据某些字段对结果进行排序才能实现。

我认为你可以做的是使用@PrimaryKeyRealmQuery.max()进行组合。

public class DataEntry {
    @PrimaryKey
    private long id;
    // ...
}

private void addEntry(DataEntry entry){
    realm.beginTransaction();
    RealmResults<DataEntry> results = realm.where(DataEntry.class).findAllSorted("id");
    if (results.count.size() >= 100) {
    // Remove the first entry
        results.get(0).removeFromRealm();
    }
    // NOTE: Consider the integer overflow and the empty results here!!!!
    entry.setId(restuls.max("id").longValue() + 1;
    realm.copyToRealm(entry);
    realm.commitTransaction();
}

id不会在[1-100]范围内,但我相信你可以做一些数学计算来实现这一目标。

答案 1 :(得分:0)

使用主键并排序为beeender建议工作。我将时间戳修改为主键,并包含MPChartLib似乎需要的时间戳的字符串版本。

所以我的DataEntry Realm数据库

@RealmClass
public class DataEntry extends RealmObject {

private String sTimestamp;
private String androidDevice;

private float x;
private float y;
private float z;
private int accuracy;

@PrimaryKey
private long timestamp;

//  no arguments constructor for Realm database
public DataEntry() {
}

public DataEntry(float x, float y, float z, long timestamp, String sTimestamp) {
    this.x = x;
    this.y = y;
    this.z = z;
    this.timestamp = timestamp;
    this.sTimestamp = sTimestamp;
}

更新数据库的代码:

    @Subscribe
public void onSensorUpdatedEvent(SensorUpdatedEvent event) {
    if (event.getSensor().getId() == this.sensor.getId()) {

        mRealm.beginTransaction();
        RealmResults<DataEntry> results = mRealm.
                where(DataEntry.class).findAllSorted("timestamp");
        if (results.size() == 1) {
            startTime = results.get(0).getTimestamp();
//            Log.i(TAG, "first data received: startTime " + startTime);
        }
//            Log.i(TAG, "check size of the database "   +results.size());
        if (results.size() >= 100) {
//            Log.i(TAG, "remove the first element of the database ");
            results.get(0).removeFromRealm();
        }
//            Log.i(TAG, "create element for the database ");
        DataEntry entry = mRealm.createObject(DataEntry.class);

        entry.setAndroidDevice(mAndroidId);
        long mTime = (long) (event.getDataPoint().getTimestamp()-startTime );
//        Log.i(TAG, "time set at   = "   +mTime);
        entry.setTimestamp(mTime);
//        currT.setText(precsion.format(mTime));
        entry.setsTimestamp(String.valueOf(mTime));
        if (event.getDataPoint().getValues().length > 0) {
            entry.setX(event.getDataPoint().getValues()[0]);
            currX.setText(precsion.format(event.getDataPoint().getValues()[0]));
        } else {
            entry.setX(0.0f);
        }

        if (event.getDataPoint().getValues().length > 1) {
            entry.setY(event.getDataPoint().getValues()[1]);
            currY.setText(precsion.format(event.getDataPoint().getValues()[1]));
        } else {
            entry.setY(0.0f);
        }

        if (event.getDataPoint().getValues().length > 2) {
            entry.setZ(event.getDataPoint().getValues()[2]);
            currZ.setText(precsion.format(event.getDataPoint().getValues()[2]));
        } else {
            entry.setZ(0.0f);
        }
        deltaT.setText(precsion.format((event.getDataPoint().getTimestamp() - lastT) / scaleT));
        totalT = ((event.getDataPoint().getTimestamp() - lastT ) / scaleT) * results.size()/1000;
        totalTText.setText(String.valueOf(totalT));
        lastT = event.getDataPoint().getTimestamp();
        entry.setAccuracy(event.getDataPoint().getAccuracy());
//          Log.i(TAG, "copy element to the database ");
        mRealm.copyToRealm(entry);
//          Log.i(TAG, " database  has size =  " + results.size());
        mRealm.commitTransaction();

    }
}

然后将数据设置为MPChartLib格式

    private void setData() {
//      Log.i(TAG, "In setData perform database query , sort by timestamp");
    RealmResults<DataEntry> result1 = mRealm.where(DataEntry.class).findAllSorted("timestamp");
//       Log.i(TAG, "set Database size is =  " + result1.size());
//       Log.i(TAG, "Extract x data ");
    RealmLineDataSet<DataEntry> set1 = new RealmLineDataSet<>(result1, "x");
    set1.setDrawCubic(false);
    set1.setLabel("Realm X");
    set1.setDrawCircleHole(false);
    set1.setColor(ColorTemplate.rgb("#FF5722"));
    set1.setCircleColor(ColorTemplate.rgb("#FF5722"));
    set1.setLineWidth(1.8f);
    set1.setCircleSize(3.6f);
//      Log.i(TAG, "Extract y data ");
    RealmLineDataSet<DataEntry> set2 = new RealmLineDataSet<>(result1, "y");
    set1.setDrawCubic(false);
    set1.setLabel("Realm Y");
    set1.setDrawCircleHole(false);
    set1.setColor(ColorTemplate.rgb("#FF5722"));
    set1.setCircleColor(ColorTemplate.rgb("#FF5722"));
    set1.setLineWidth(1.8f);
    set1.setCircleSize(3.6f);
//      Log.i(TAG, "Extract z data ");
    RealmLineDataSet<DataEntry> set3 = new RealmLineDataSet<>(result1, "z");
    set1.setDrawCubic(false);
    set1.setLabel("Realm Z");
    set1.setDrawCircleHole(false);
    set1.setColor(ColorTemplate.rgb("#FF5722"));
    set1.setCircleColor(ColorTemplate.rgb("#FF5722"));
    set1.setLineWidth(1.8f);
    set1.setCircleSize(3.6f);
//      Log.i(TAG, "add datasets ");
    ArrayList<ILineDataSet> dataSets = new ArrayList<>();
    dataSets.add(set1);
    dataSets.add(set2);
    dataSets.add(set3);
//       Log.i(TAG, "Create Line Data for graphing " );
    RealmLineData lineData = new RealmLineData(result1, "sTimestamp", dataSets);
//       Log.i(TAG, "Set Data on Chart ");
    mChart.setData(lineData);
//       Log.i(TAG, "Re-draw ");
    mChart.invalidate();
}

我没有x轴标签,因为它们是巨大的数字。我的计划是关闭轴标签。