由于空对象引用,无法将新对象添加到RealmList。

3
我有两个Realm对象,一个是基本的RealmObject,包含两个字符串和一个布尔值,另一个是该对象的RealmList,以便更容易地访问。当我尝试从我的ContactBook实例中获取列表并添加新对象时,我会得到“尝试调用空对象引用的虚拟方法”的错误。但我能够获得contactBook的大小和联系人数量,因此它们不是null。
尝试添加新对象的类:
public void viewSetup() {
    setContentView(R.layout.activity_contacts);
    ButterKnife.inject(this);
    Realm.deleteRealmFile(this);
    realm = Realm.getInstance(this);
    results = realm.where(ContactBook.class).findAll();
    if (toolbar != null) {
        setSupportActionBar(toolbar);
    }

    if (results.size() == 0) {
        realm.beginTransaction();
        ContactBook contactBook = realm.copyToRealm(new ContactBook());
        realm.commitTransaction();
    }
}

public void setupCursor() {
    Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
    ContactBook contactBook = results.first();

    realm.beginTransaction();
    while (cursor.moveToNext()) {
        String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
        String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
        if (contactBook.getContacts().where().equalTo("name", name).findAll().size() == 0 && contactBook.getContacts().where().equalTo("number", number).findAll().size() == 0) {
            contactBook.getContacts().add(new Contact(name, number, false));
        }
    }
    realm.commitTransaction();



    cursor.close();
}

一个包含两个字符串和布尔值的类

public class Contact extends RealmObject {

private String name;
private String number;
private boolean allowed;

public Contact() {

}

public Contact(String name, String number, boolean allowed) {
    this.name = name;
    this.number = number;
    this.allowed = allowed;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getNumber() {
    return number;
}

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

public boolean isAllowed() {
    return allowed;
}

public void setAllowed(boolean allowed) {
    this.allowed = allowed;
}
}

联系人类

public class ContactBook extends RealmObject {

private RealmList<Contact> contacts = new RealmList<>();

public ContactBook() {

}

public RealmList<Contact> getContacts() {
    return contacts;
}

public void setContacts(RealmList<Contact> contactBook) {
    this.contacts = contactBook;
}
}

错误日志
    java.lang.RuntimeException: Unable to start activity ComponentInfo{io.github.brady131313.textback/io.github.brady131313.textback.View.ActivityContactSelect}: java.lang.NullPointerException: Attempt to invoke virtual method 'long io.realm.internal.Row.getIndex()' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2661)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
        at android.app.ActivityThread.access$900(ActivityThread.java:172)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:145)
        at android.app.ActivityThread.main(ActivityThread.java:5835)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'long io.realm.internal.Row.getIndex()' on a null object reference
        at io.realm.RealmList.add(RealmList.java:122)
        at io.github.brady131313.textback.View.ActivityContactSelect.setupCursor(ActivityContactSelect.java:69)
        at io.github.brady131313.textback.View.ActivityContactSelect.onCreate(ActivityContactSelect.java:39)
        at android.app.Activity.performCreate(Activity.java:6221)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2614)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
            at android.app.ActivityThread.access$900(ActivityThread.java:172)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:145)
            at android.app.ActivityThread.main(ActivityThread.java:5835)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)

错误发生在从setupCursor调用的setContacts内部。但是您的setupCursor方法没有调用setContents。这是您真实的代码和日志吗?(我不知道Realms的具体情况) - user253751
你确定在尝试将namenumber插入到你的Realm之前,它们都不是null吗? - Emanuelez
如果我将它们添加到ArrayList中,整个设置都可以正常工作,并且从那里我能够记录所有联系人。即使我手动添加一个对象,我仍然会得到相同的错误。 - Brady131313
1个回答

10

这是因为你试图将非托管对象添加到托管列表中。以下是代码:

if (contactBook.getContacts().where().equalTo("name", name).findAll().size() == 0 && contactBook.getContacts().where().equalTo("number", number).findAll().size() == 0) {
    contactBook.getContacts().add(new Contact(name, number, false));
}

应该是:

if (contactBook.getContacts().where().equalTo("name", name).findAll().size() == 0 && contactBook.getContacts().where().equalTo("number", number).findAll().size() == 0) {
    Contact newContact = realm.copyToRealm(new Contact(name, number, false));
    contactBook.getContacts().add(newContact);
}

使用new运算符创建的对象无法直接添加到已经存在于Realm中的RealmLists中,必须使用其中一种Realm.copyToRealmXXX方法将其转换为正确(或受管理)的Realm对象。但错误消息肯定可以更好。


2
这个关于托管/非托管对象的问题只是造成混淆的一个主要原因。 - Alex Dmitriev
我觉得这并不是很好。在使用实体之前,你只需要将它们“插入”即可 :P - josemigallas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接