将 RealmList<Object> 设置为我的数据库项目,使用 Realm for android

Issue setting a RealmList<Object> to my database item, using Realm for android

首先,我调用了一个函数,该函数将从数据库中恢复我的用户,在我从 WS 获取更新后的个人资料后,我尝试从数据库中更改好友列表。

获取用户的方法:

 public UserRecord getMyUser(){
    String userId = PSLocationCenter.getInstance().pref.getUserId(context);
    RealmResults<UserRecord> completed = realm.where(UserRecord.class).equalTo("id" , userId).findAll();
    if(completed.size() > 0){
        return completed.get(0);
    }else{
        return null;
    }
}

之后,这是我从中获取数据的 WSCall,并尝试更改好友列表:

user = UserRecordDBFactory.getInstance(PSProfileActivity.this).getMyUser();
WSCalls.getData("/api/users/" + user.getId() + "/friends", PSProfileActivity.this, loader, new JsonCallback() {
                        @Override
                        public void onResponse(JSONObject jsonObject) {
                            try {
                                FriendsResponse friendsResponse = JsonUtil.jsonToObject(jsonObject.toString(), FriendsResponse.class);
                                Log.i("","friends response: " + friendsResponse.toString());
                                Log.i("","friends response: " + friendsResponse.getFriends());
                                friends = friendsResponse.getFriends();
                                Log.i("","friends after being given the response: " + friends.size());
                                Log.i("","friends USER after being given the response: " + user);
                                Log.i("","friends USER after being given the response: " + user.getId());
                                Realm realm = Realm.getInstance(PSProfileActivity.this);
                                realm.beginTransaction();
                                user.setFriends(friends);
                                Log.i("", "friends set to user: " + friends);
                                realm.commitTransaction();
                                UserRecordDBFactory.getInstance(PSProfileActivity.this).updateMyUser(user);
                                Log.i("", "friends set to user in REALM: " + friends);
                                setHeaderAndData(profile);
                            } catch (Exception e) {
                                Utils.appendLog("onresume friends activ error: " + e.getMessage());
                                Log.e("", "getProfileData - JsonException: " + e.getMessage());
                            }
                        }
                    });

这是我得到的日志:

03-10 18:02:13.826  23882-23882/nl.hgrams.passenger I/﹕ friends response: nl.hgrams.passenger.model.FriendsResponse@1635594a
03-10 18:02:13.827  23882-23882/nl.hgrams.passenger I/﹕ friends response: RealmList@[254263483,474495448,561029425,720879638,789032343,921901956,66920301,229099426,948931635,877161456,1062815081,73317358,28096655,610293532,322424613,192850170,667307691]
03-10 18:02:13.827  23882-23882/nl.hgrams.passenger I/﹕ friends after being given the response: 17
03-10 18:02:13.829  23882-23882/nl.hgrams.passenger I/﹕ friends USER after being given the response: UserRecord = [{username:},{first_name:Alin},{last_name:Red},{email:r@y.com},{token:8596bcb0243cc16b6f16e5e90210754c65f8e58ca426daecd3d7220d5092e24d},{id:6},{bio:Red},{image:/media/user_image/8b824838993f3c5aae2bfb650851e7e1.jpe},{nrTrips:0},{distance:0},{last_destination:},{friends:RealmList<Friend>[0]},{activityLog:null},{recents:RealmList<SearchData>[0]},{updateRecents:false}]
03-10 18:02:13.829  23882-23882/nl.hgrams.passenger I/﹕ friends USER after being given the response: 6
03-10 18:02:13.836  23882-23882/nl.hgrams.passenger E/﹕ getProfileData - JsonException: Attempt to invoke virtual method 'long io.realm.internal.Row.getIndex()' on a null object reference

这是我的 setter 来自 RealmObject class:

public void setFriends(RealmList<Friend> fr) {
    Log.i("","before in set friends");
    friends = fr;
    Log.i("","after in set friends");
}

并且它不会记录来自 getter 的任何日志。如您所见,我还制作了日志来检查用户或朋友是否为空,但事实并非如此。 知道我在这里做错了什么吗? 看到它尝试了很长时间 io.realm.internal.Row.getIndex(),我猜它发现用户不知何故为空,但为什么呢?

这就是 jsonToObject 函数的作用:

public static <T> T jsonToObject(String json, Class<T> toClass) throws Exception {
    if (instance == null) {
        instance = new JsonUtil();
    }
    return instance.gson.fromJson(json, toClass);
}

实例gson所在位置:

gson = new GsonBuilder()
            .setExclusionStrategies(new ExclusionStrategy() {
                @Override
                public boolean shouldSkipField(FieldAttributes f) {
                    return f.getDeclaringClass().equals(RealmObject.class);
                }

                @Override
                public boolean shouldSkipClass(Class<?> clazz) {
                    return false;
                }
            })
            .create();

而且我的 UserRecord 中只有 RealmObjects,我不使用普通对象

是不是像这样,而且成功了:

WSCalls.getData("/api/users/" + user.getId() + "/friends", PSProfileActivity.this, loader, new JsonCallback() {
                        @Override
                        public void onResponse(JSONObject jsonObject) {
                            try {
                                FriendsResponse friendsResponse = JsonUtil.jsonToObject(jsonObject.toString(), FriendsResponse.class);
                                Log.i("","friends response: " + friendsResponse.getFriends());
                                Realm realm = Realm.getInstance(PSProfileActivity.this);
                                friends = friendsResponse.getFriends();
                                for (UserRecord friend : friends) {
                                    friend.setDistanceTraveled(friend.getStats().getDistanceTraveled());
                                }
                                Log.i("","first begin transaction");
                                realm.beginTransaction();
                                List<UserRecord> list = realm.copyToRealmOrUpdate(friends);
                                realm.commitTransaction();

                                Log.i("", "second begin transaction");
                                realm.beginTransaction();
                                user.getFriends().clear();
                                for (UserRecord friend : list) {
                                    user.getFriends().add(friend);
                                }
                                realm.commitTransaction();
                                Log.i("", "third begin transaction");

                                setHeaderAndData(profile);
                            } catch (Exception e) {
                                Utils.appendLog("onresume friends activ error: " + e.getMessage());
                                Log.e("", "getProfileData - JsonException: " + e.getMessage());
                            }
                        }
                    });

需要先将列表复制到领域,然后使用托管项目添加到我的项目上,以便提交我的项目

我相信如果您这样做,您可以避免遍历所有朋友并单独添加他们:

    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            List<Friend> realmFriends = realm.copyToRealmOrUpdate(friends);
            RealmList<Message> realmListFriends = new RealmList<>(realmFriends.toArray(new Friend[friends.size()]));
            user.setFriends(realmListFriends);
        }
    });

编辑:需要说明的是,您仍在方法 Collection.toArray() 内部迭代您的好友。复杂度还是O(n),但是代码可读性更好