0

我想为这种情况设置一个自定义分辨率: 1- 在离线模式下在一个设备中增加领域对象中的整数字段 2- 在离线模式下在另一台设备中增加同一领域对象中的相同整数字段 默认自定义分辨率是上次更新获胜但在我的情况下,我希望两个设备的增量在上线后对结果生效,而不是最后一次更新。我尝试了这段代码进行测试:

Realm realm = Realm.getDefaultInstance();
            final RealmResults<Number> results= realm.where(Number.class).findAll();

            realm.executeTransaction(new Realm.Transaction() {
                @Override
                public void execute(Realm realm) {
                    int num = results.get(0).getNumber()+1;
                    results.get(0).setNumber(num);
                }
            });

Number 类是这样的:

public class Number extends RealmObject {
@PrimaryKey
private String id;
private int number;

public String getId() {
    return id;
}
public void increment(){
    this.number++;
}
public void setId(String id) {
    this.id = id;
}

public int getNumber() {
    return number;
}

public void setNumber(int number) {
    this.number = number;
}

这个问题对我的应用程序非常关键。如果我不能在客户端执行此操作,我将无法使用我非常感兴趣的领域移动平台。

4

3 回答 3

0

感谢@ast 代码示例。我还通过缓存命令模式解决了这个问题,这是我的代码:

public class CommandPattern extends RealmObject {
@PrimaryKey
private String id;
private String commandName;

public String getCommandName() {
    return commandName;
}

public void setCommandName(String commandName) {
    this.commandName = commandName;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}}
 @Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_increment:
            if (isOnline()) {
                realm = Realm.getDefaultInstance();
                realm.executeTransaction(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        updateNumberOnRealm();
                    }
                });
                realm.close();
            } else {
                addMethodToCache("increment");
            }
public void addMethodToCache(final String methodName) {
    realm = Realm.getDefaultInstance();
    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            commandPattern = new CommandPattern();
            commandPattern.setId(UUID.randomUUID().toString());
            commandPattern.setCommandName(methodName);
            realm.copyToRealmOrUpdate(commandPattern);
        }
    });
    realm.close();
}

public void invokeCachedCommands() {
    realm = Realm.getDefaultInstance();
    commandsCached = realm.where(CommandPattern.class).findAll();
    commandsCached.addChangeListener(new RealmChangeListener<RealmResults<CommandPattern>>() {
        @Override
        public void onChange(final RealmResults<CommandPattern> element) {
            if(!element.isEmpty()) {
                realm.executeTransaction(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        for (CommandPattern command : element) {
                            if(command != null) {
                                if (command.getCommandName().equals("increment")) {
                                    //updateNumberOnRealm();
                                    RealmResults<Number> results = realm.where(Number.class).findAll();
                                    results.get(0).increment();
                                    command.deleteFromRealm();
                                }
                            }
                        }
                    }

                });
            }
        }

    });


    realm.close();

}

在完成增量操作之前,我检查联机状态,如果它处于脱机状态,则在再次联机后缓存在命令模式对象中的增量字符串通过以下代码调用这些缓存的命令:

IntentFilter intentFilter = new IntentFilter(NetworkStateChangeReceiver.NETWORK_AVAILABLE_ACTION);
    LocalBroadcastManager.getInstance(this).registerReceiver(new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            boolean isNetworkAvailable = intent.getBooleanExtra(IS_NETWORK_AVAILABLE, false);
            if (isNetworkAvailable) {
                invokeCachedCommands();
            }else{
                if(commandsCached != null) {
                    commandsCached.removeChangeListeners();
                }
            }

        }
    }, intentFilter);

这是通用的自定义冲突解决方案,可用于任何类型的命令

于 2016-12-29T06:41:44.707 回答
0

文档目前说协议支持计数器,但尚未在语言级别公开,所以我想你必须自己实现它。

最简单的方法是将其存储为List整数(1用于递增,-1用于递减),然后使用List.sum()https://realm.io/docs/java/2.2.1/api/io/realm/RealmList.html #sum-java.lang.String- ) 以快速获取聚合结果。

public class Counter extends RealmObject {
    private int count;

    public int    getCount() { return count; }
    public void   setCount(int count) { this.count = count; }
}

public class Number extends RealmObject {
    @PrimaryKey
    private String id;
    private RealmList<Counter> counters;

    public void incrementNumber(){
        Counter c = realm.createObject(Counter.class);
        c.setCount(1);
        this.getCounters().add(c);
    }

    public int getNumber() {
        // Get the aggregate result of all inc/decr
        return this.getCounters().sum("count");
    }

    public void setNumber(int number) {
        this.getCounters().deleteAllFromRealm();

        Counter c = realm.createObject(Counter.class);
        c.setCount(number);
        this.getCounters().add(c);
    }

    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    private RealmList<Counter> getCounters() { return counters; }
    private void setCounters(RealmList<Counter> counters) { this.counters = counters; }
}

```

于 2016-12-28T19:44:42.250 回答
0

也许您可以对此类对象使用命令列表,将它们保持在离线状态并在上线时同步/合并。命令可以是increment,decrementmultiplyBy2

文档说:

    Inserts in lists are ordered by time. 
    If two items are inserted at the same position, the item that was
    inserted first will end up before the other item. This means that
    if both sides append items to the end of a list they will end up in
    order of insertion time.

因此,您将始终拥有按日期排序的应用命令列表。

于 2016-12-27T21:52:52.363 回答