Realm 初次使用及踩坑

版权声明:本文为博主原创文章,转载请保留原作者名和原文链接。 https://blog.csdn.net/Likianta/article/details/80312610

配置篇

不建议在 Realm 中使用 Stetho(2018-5-14)

目前在 Realm 中配置 Stetho 的方法为使用 realm-stetho,但 realm-stetho 仅支持到 Realm v3.x 的版本。

如果你的 Realm 版本为 4.3.1+,那么将会 build 失败。

替代的工具为 Realm Studio—— 一款 Realm 官方出品的 Realm 数据库查看和管理工具;现已支持 Mac、Windows、Linux 三平台。


初始化及构造函数篇

JavaBean 必须使用(或包含)无参构造方法

什么是无参构造方法?就是没有参数的构造体,如下所示:

// JavaBean - User.class
public class User extends RealmObject {

    @PrimaryKey
    private long id;
    private String name;


    // Notice: must have this
    public User() {

    }

    // Optional
    public User(long id, String name) {
        this.id = id;
        this.name = name;
    }

    // Getter and setter...

}

如果忘记加无参构造方法,那么在 build 时会出现“compileJavaWithJavac”这个奇怪的错误(而且这个报告默认是没有详细信息的,因此很难追踪到问题来源),所以一定要加上。

PS:如果什么都不写也是可以的,JVM 会自动生成无参构造方法。例如:

// JavaBean - User.class
public class User extends RealmObject {

    @PrimaryKey
    private long id;
    private String name;

    // Getter and setter...

}

多对一关系使用 RealmList<> 不要使用 List<>

// Assumed User class contains many user photos
public class User extends RealmObject {

    @PrimaryKey
    private long id;
    private String name;

    // Correct
    private RealmList<Photo> userPhotos;
    // Incorrect
    private List<Photo> userPhotos = new ArrayList<>();

    // Getter and setter...

}

另外注意在子类 Photo.class 中不要有父对象 private User user

子对象不应有主键

// Assumed Photo.class is the child of User.class
public class Photo extends RealmObject {
    // Incorrect
    @PrimaryKey
    private long id;

    // ...
}

不要在 JavaBean 中使用自增主键

// User.class
public class User extends RealmObject {

    @PrimaryKey
    private long id;
    private String name;

    // Incorrect
    public User() {
        this.id = UUIDGenerator.getUUID(); // assumed you can get an unique id by this method...
    }
    // Correct
    public User() {

    }

    // Getter and setter...

}

主键类型不可以设为 int

// User.class
public class User extends RealmObject {

    // Don't
    @PrimaryKey
    private int id;

    // Do
    @PrimaryKey
    private long id;
    // Or
    @PrimaryKey
    private String id;

    // Getter and setter...
}

对 javabean 中的成员进行修改后,需要重装 app 才能正常运行

// User.class (Before)
public class User extends RealmObject {

    // Before: a type of "long"...
    @PrimaryKey
    private long id;

    // Getter and setter...
}

// User.class (After)
public class User extends RealmObject {

    // After: change type to "String"
    // You should uninstall the existed app in your phone (or simulator) before you rerun app
    @PrimaryKey
    private String id;

    // Getter and setter...
}

CRUD 篇

使用 copyToRealmOrUpdate() 取代 copyToRealm()

// Assumed you've got a List<User> userList and a Realm realm...

// Don't
realm.copyToRealm(userList);

// Do
realm.copyToRealmOrUpdate(userList);

使用 createObject(User.class, anId) 取代 createObject(User.class, new User())

private User generateUser(String userName, RealmList<Photo> userPhotos) {
    final String anId = UUIDGenerator.getUUID(); // assumed you can get an unique id by this method

    Realm realm = Realm.getDefaultInstance();
    realm.beginTransaction();

    // Do
    User user = realm.createObject(User.class, anId);
    // Don't
    User user = realm.createObject(User.class, new User());
    User user = realm.createObject(User.class, new User(anId)); // also don't 1
    User user = realm.createObject(User.class); // also don't 2

    // Assumed User.class has 2 members:
    // String userName and RealmList<Photo> userPhotos
    user.setUserName(userName);
    user.setUserPhotos(userPhotos);

    realm.insertOrUpdate(user); // not recommended using `realm.insert(user)`
    realm.commitTransaction();

    return user;
}

静态方法中不要写 beginTransaction()commitTransaction()

// Activity1.class
public class Activity1 {
    private void fn1() {
        Realm realm = Realm.getDefaultInstance();

        realm.beginTransaction();

        Activity2.fn2();

        realm.commitTransaction();
    }
}


// Activity2.class
public class Activity2 {
    private static void fn2() {
        Realm realm = Realm.getDefaultInstance();
        // Don't use beginTransaction() here
        // realm.beginTransaction();

        User user = new User("sdaadfoiwjfsa", "Jack"); // id and userName

        realm.insertOrUpdate(user);

        // And don't use commitTransaction()
        // realm.commitTransaction();
    }
}

猜你喜欢

转载自blog.csdn.net/Likianta/article/details/80312610