更新托管对象字段的领域变慢

Realm slow with updating managed object's field

我有一个相当简单的托管 Realm 对象 RealmAlertItem,由一些字符串和浮点数组成。我有一个函数 showAlertNotification() 随后被调用(从网络外部触发),它依赖于上一次执行在下一次调用之前完全完成的事实。在这个函数中,我只更改了一个浮点字段(参见下面的 setHigh()setLow())。如果两者都是 0,我删除该对象。

然而,似乎 Realm 无法及时更新对象,在第二次调用该函数时,对象仍然具有旧的 highlow 值。

这里是logcat:

08:47:04.180 D/debug: showAlertNotification(), guid: 58dfe381-b615-4ce0-beaf-5abb9b0733ac
08:47:04.185 D/debug: high 10000.0 , low 10800.0
08:47:04.205 D/debug: b // here we call RealmInstance.getThreadRealm().executeTransaction(realm1 -> alert.setHigh(0));
08:47:04.214 /debug: showAlertNotification(), guid: 58dfe381-b615-4ce0-beaf-5abb9b0733ac
08:47:04.215 /debug: high 10000.0 , low 10800.0 // here high should be 0!
08:47:04.224 /debug: d

如您所见,第二次调用在第一次调用之后发生得非常快(大约 30 毫秒后)。

代码如下:

private void showAlertNotification(RemoteMessage remoteMessage, String coinSlug, String coinName, Bitmap logo) {
    Log.d("debug", "showAlertNotification(), guid: " + remoteMessage.getData().get("guid"));

    RealmAlertItem alert = RealmInstance.getThreadRealm().where(RealmAlertItem.class).equalTo("guid", remoteMessage.getData().get("guid")).findFirst();
    if(alert == null)
        return;


    ... some work


    // disable/delete this alert
    if(!alert.isRepeating()) {
        if (isHighLimit) {
            if (alert.getLow() == 0) {
                Log.d("debug", "a");
                RealmInstance.getThreadRealm().executeTransaction(realm1 -> alert.deleteFromRealm());
            } else {
                Log.d("debug", "b");
                RealmInstance.getThreadRealm().executeTransaction(realm1 -> alert.setHigh(0));
            }
        } else {
            if (alert.getHigh() == 0) {
                Log.d("debug", "c");
                RealmInstance.getThreadRealm().executeTransaction(realm1 -> alert.deleteFromRealm());
            } else {
                Log.d("debug", "d");
                RealmInstance.getThreadRealm().executeTransaction(realm1 -> alert.setLow(0));
            }
        }
    }

    Intent intent = new Intent("notifyAlertsChanged");
    LocalBroadcastManager.getInstance(MainApplication.getAppContext()).sendBroadcast(intent);
}

如果需要,这是我的 RealmInstance Singleton:

public class RealmInstance {
    private Realm realm;
    private static RealmInstance realmInstance;

    public static RealmInstance getInstance() {
        if (realmInstance == null) {
            realmInstance = new RealmInstance();
        }
        return realmInstance;
    }

    private RealmInstance() {
        try {
            realm = Realm.getDefaultInstance();
        } catch (IllegalStateException err) {
            init(MainApplication.getAppContext());
            realm = Realm.getDefaultInstance();
        }
    }

    public Realm getRealm() {
        return realm;
    }

    public static Realm getThreadRealm() {
        return Realm.getDefaultInstance();
    }

    public static void init(Context context) {
        Realm.init(context);

        RealmConfiguration config = new RealmConfiguration
                .Builder()
                .schemaVersion(13)
                .deleteRealmIfMigrationNeeded()
                .build();

        Realm.setDefaultConfiguration(config);
    }
}

我该如何解决这个问题?

您需要在 Application.java 中初始化您的 Realm 配置,并在需要时调用 Realm.getDefaultInstance()(即摆脱您的单例 class)。

您还需要在使用后关闭 realm 实例,否则您在试验时会产生副作用,稍后您会遇到性能问题。