承接上篇 从零开始的 Android 新项目(5):Repository 层(上),本文继续介绍Realm、缓存,以及统一的异常处理设计。
Realm
Realm在移动端数据库中也算是比较有名的一款了,以其跨平台和惊人的速度而闻名。啊,对了,还有文档多。
这里要黑的就是文档问题,Realm虽然乍一看文档很多,但是老实说,写的挺乱的。不过总体来说,实践和应用中感觉还不错,性能好,也比较方便,比起不稳定的DBFlow和麻烦至极的GreenDao来好了太多了,唯一的美中不足就是so比较大,会增大包的体积1MB。
引入
从Realm 0.90开始,用法与之前有了改变:
在root的build.gralde中:
1 2 3 4 5 6 7 8 |
buildscript { repositories { jcenter() } dependencies { classpath "io.realm:realm-gradle-plugin:0.90.1" } } |
然后在对应需要应用到Realm的,比如data module的build.gradle:
1 |
apply plugin: 'realm-android' |
即可使用Realm。
使用
使用起来也很方便,比如我们想要缓存用户的信息
1 2 3 4 5 6 7 |
public class UserPo extends RealmObject { @PrimaryKey public String id; public String name; public String headerUrl; public long updateTime; } |
这样就对应了一个表,其主键为id,另外有3列name, headerUrl, 以及updateTime。
如果想要查询,只需要:
1 2 3 |
UserPo user = getRealm().where(UserPo.class) .equalTo("id", userId) .findFirst(); |
如果要写入一条记录:
1 2 3 4 5 6 7 8 9 |
User user = new UserPo(); user.setName(userInfoEntity.getNickName()); user.setId(userInfoEntity.getUserId()); user.setHeaderUrl(userInfoEntity.getHeaderImageUrl()); user.setUpdateTime(System.currentTimeMillis()); getRealm().beginTransaction(); getRealm().copyToRealmOrUpdate(user); getRealm().commitTransaction(); |
就是这么简单。
如果想要直接和Retrofit一起应用,去进行串行化,可以参考该Gist。
1 2 3 4 5 6 7 8 9 10 |
// 结合 Realm, Retrofit 和 RxJava (使用了Retrolambda以简化符号)的例子。 // 读取所有Person,然后与从GitHub获取的最新状态merge到一起 Realm realm = Realm.getDefaultInstance(); GitHubService api = retrofit.create(GitHubService.class); realm.where(Person.class).isNotNull("username").findAllAsync().asObservable() .filter(persons.isLoaded) .flatMap(persons -> Observable.from(persons)) .flatMap(person -> api.user(person.getGithubUserName()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(user -> showUser(user)); |
更多详情可以去官网看,migration/relationship等等支持应有尽有,我只能说,文档实在太长太长了。
内存
内存,也就是直接使用变量存储在对应repository中,如果非空则优先直接返回内存中的变量。
LruCache
LruCache限定了最大的entry数量,近期最少使用算法保证了淘汰机制的合理性。使用场景如用户信息缓存,会淘汰那些最近没有访问过的用户的信息缓存。使用可参考Google官网:m">Realm
Realm在移动端数据库中也算是比较有名的一款了,以其跨平台和惊人的速度而闻名。啊,对了,还有文档多。
这里要黑的就是文档问题,Realm虽然乍一看文档很多,但是老实说,写的挺乱的。不过总体来说,实践和应用中感觉还不错,性能好,也比较方便,比起不稳定的DBFlow和麻烦至极的GreenDao来好了太多了,唯一的美中不足就是so比较大,会增大包的体积1MB。
引入
从Realm 0.90开始,用法与之前有了改变:
在root的build.gralde中:
1 2 3 4 5 6 7 8 |
buildscript { repositories { jcenter() } dependencies { classpath "io.realm:realm-gradle-plugin:0.90.1" } } |
然后在对应需要应用到Realm的,比如data module的build.gradle:
1 |
apply plugin: 'realm-android' |
即可使用Realm。
使用
使用起来也很方便,比如我们想要缓存用户的信息
1 2 3 4 5 6 7 |
public class UserPo extends RealmObject { @PrimaryKey public String id; public String name; public String headerUrl; public long updateTime; } |
这样就对应了一个表,其主键为id,另外有3列name, headerUrl, 以及updateTime。
如果想要查询,只需要:
1 2 3 |
UserPo user = getRealm().where(UserPo.class) .equalTo("id", userId) .findFirst(); |
如果要写入一条记录:
1 2 3 4 5 6 7 8 9 |
User user = new UserPo(); user.setName(userInfoEntity.getNickName()); user.setId(userInfoEntity.getUserId()); user.setHeaderUrl(userInfoEntity.getHeaderImageUrl()); user.setUpdateTime(System.currentTimeMillis()); getRealm().beginTransaction(); getRealm().copyToRealmOrUpdate(user); getRealm().commitTransaction(); |
就是这么简单。
如果想要直接和Retrofit一起应用,去进行串行化,可以参考该Gist。
1 2 3 4 5 6 7 8 9 10 |
// 结合 Realm, Retrofit 和 RxJava (使用了Retrolambda以简化符号)的例子。 // 读取所有Person,然后与从GitHub获取的最新状态merge到一起 Realm realm = Realm.getDefaultInstance(); GitHubService api = retrofit.create(GitHubService.class); realm.where(Person.class).isNotNull("username").findAllAsync().asObservable() .filter(persons.isLoaded) .flatMap(persons -> Observable.from(persons)) .flatMap(person -> api.user(person.getGithubUserName()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(user -> showUser(user)); |
更多详情可以去官网看,migration/relationship等等支持应有尽有,我只能说,文档实在太长太长了。
内存
内存,也就是直接使用变量存储在对应repository中,如果非空则优先直接返回内存中的变量。
LruCache
LruCache限定了最大的entry数量,近期最少使用算法保证了淘汰机制的合理性。使用场景如用户信息缓存,会淘汰那些最近没有访问过的用户的信息缓存。使用可参考Google官网: