领域findFirst()方法返回null

时间:2016-10-15 23:43:35

标签: java android realm

我搜索并发现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

enter image description here

但是,我可以在db。

中看到我的无null用户

enter image description here

我正在使用classpath "io.realm:realm-gradle-plugin:2.0.2"

4 个答案:

答案 0 :(得分:9)

这里有两件事:

  1. 调试窗口中的null值。当使用Realm和调试器时,这是一个已知的限制。由于Realm生成了一个Proxy类来访问值,因此检查调试器中的RealmObject字段将不会通过代理类。查看更多详情here

  2. 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。