配置篇
不建议在 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();
}
}