我搜索并发现FindFirst returns null问题,但没有人回答。因为我在想我做错了什么,让我用更多细节来解释我的问题。
我正在开发一个应用程序,要求用户先登录,然后让用户使用该应用程序。
我的User
课程如下:
public class User extends RealmObject {
@PrimaryKey
@SerializedName("uid")
String id;
@SerializedName("ufname")
String firstName;
@SerializedName("ulname")
String lastName;
String avatar;
int sessions;
int invites;
String nextSessionTime;
String nextSessionTitle;
@SerializedName("lastlogin")
String lastLogin;
String token;
@Override
public String toString() {
return new GsonBuilder().create().toJson(this, User.class);
}
// other setters and getters
}
在SigninActivity
类成功登录后,我将用户的对象存储在Realm db中:
@Override
public void onSignInResponse(final GeneralResponse response) {
if (response == null) {
Timber.e("response is null");
return;
}
Timber.d(response.toString());
if (response.isSuccess()) {
// Store user's info including Token
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(response.getUser());
}
});
// Goto main screen
MainVideoActivity.startActivity(this);
this.finish();
} else {
String errorMessage = response.getErrorMessages();
super.displayMessage(errorMessage);
}
}
登录成功后,app会将用户定向到MainVideoActivity
。我希望通过以下代码在域中找到用户,但我得到null
。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_video);
// Create the Realm instance
realm = Realm.getDefaultInstance();
User user = realm.where(User.class).findFirst();
// RealmResults<User> user = realm.where(User.class).findAll();
Timber.d(user.toString());
}
user
在两种方法中均为null
。
但是,我可以在db。
中看到我的无null
用户
我正在使用classpath "io.realm:realm-gradle-plugin:2.0.2"
答案 0 :(得分:9)
这里有两件事:
调试窗口中的null
值。当使用Realm和调试器时,这是一个已知的限制。由于Realm生成了一个Proxy类来访问值,因此检查调试器中的RealmObject字段将不会通过代理类。查看更多详情here
null
方法中未打印toString()
值的字段。如果toString()
中没有定义toString()方法,则Realm注释处理器将生成RealmObject
方法。我认为这里的问题是a User.toString()
忽略空值。尝试删除User
类中的toString()方法。
答案 1 :(得分:1)
根据Realm doc Realm,您可以尝试在查询中添加isNotNull()
,如下所示:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_video);
// Create the Realm instance
realm = Realm.getDefaultInstance();
User user = realm.where(User.class).isNotNull("id").findFirst(); //add in this line isNotNull()
//RealmResults<User> user = realm.where(User.class).findAll();
Timber.d(user.toString());
}
我还没有测试过,但它应该有效。
答案 2 :(得分:1)
尝试替换
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(response.getUser());
}
});
// Goto main screen
MainVideoActivity.startActivity(this);
this.finish();
与
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(response.getUser());
}
}, new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
// Goto main screen
MainVideoActivity.startActivity(this);
finish();
}
});
答案 3 :(得分:0)
解决此问题的一种方法是创建对象的非托管副本。
替换:
User user = realm.where(User.class).findFirst();
使用
User managed_user = realm.where(User.class).findFirst();
if(user!=null){
User unmanaged_user = realm.copyFromRealm(managed_user)
}
返回unmanaged_user。