说说Realm在Android上的坑
来源:互联网 发布:吃鸡优化设置 编辑:程序博客网 时间:2024/05/17 22:07
1.前言
新项目使用了大名鼎鼎的realm,在网络上看到大量安利realm的文章,但是在使用的过程中却遇到了很多问题,这里记录下两个多月以来遇见的问题。希望大家能够理性选择,不要人云亦云。当然,,realm文档中也给出了一些当前的限制,但是,我们今天要说的,不仅仅是这些。
realm-java文档地址
2.线程的限制
通常来讲,我们查询数据库会开一个子线程查询,这次,我们也没例外,简简单单的写两行代码,如下。
realm.where(User.class) .findAll() .asObservable() .observeOn(Schedulers.io()) .subscribeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<RealmResults<User>>() { @Override public void call(RealmResults<User> users) { users.get(0); } });
当我们满心欢喜的运行起来的时候,mdzz,crash了。日志如下。
what,realm对象只能在他被创建的线程中访问,搞毛啊。即使你查询速度快,也提供了异步查询,可我就想在子线程和主现场之间切换玩。这。。。不是坑么。
3.RealmList的问题
说到这里,我们先来看看realm支持的数据类型。
很好,基本能满足我们的需求。并且还提供了RealmList来提供给我们使用。这次,我要实现这样的需求,在a1中查询数据出来,传递到a2中,由于实体较复杂,内含多对一的对应关系,这里是用RealmList来处理了。写好代码,不幸的是,又crash了。
这次的错误,预示这我们,realm intent传值又问题。
我们的实体对象是这样写的。
public class User extends RealmObject implements Serializable{ public String name; public RealmList<Cursor> cursors;}
忽略我不标准的写法
很明显,问题出在了realmlist这里,我们进去一看,fuck,和arraylist的区别很明显。如图。
可以看到,arraylist是实现的Serializable接口的,而realmlist却没有,因此,我们在使用用了realmlist的实体类的时候,使用intent传值就回出现问题,要注意了。
解决办法:我们只能存入数据库,在第二个界面进行查询使用,这不是我想要的。
4.查询出来的数据,intent传值问题
没想到吧,即使简简单单的查询出来的数据,在使用intent传值还是有问题。这次我的实体类变成这样。
public class User extends RealmObject implements Serializable{ public String name;}
接下来,我们将查询出来的数据,使用intent传递到第二个界面。
细心的同学应该看出来了,这里crash的原因是因为我们userrealmproxy不能被序列化的问题。但是,我们没有传过userrealmproxy啊。这是因为我们查询出来的数据,不再是我们想要的对象,而是realm用apt给我们生成的实体类的子类,或者说是实体类的代理类,在realm中起到作用的,就是这些个代理类。在build目录下我们能找到不少。如图。
解决办法,实现cloneable接口,深clone或者是把查询到的值手动复制给我们new的实体类对象。这也不是我们想要的结果
5. RealmChangeListener的坑
我们确实需要它来通知我们异步查询什么时候结束。但是,我们要注意后半句,当realmresults对象更新的时候,也会通知我们。
现在,我们思考一个场景,我们要在进入页面的时候,查询数据,显示界面。并且同时请求网络,更新数据,更新界面,没错,这个场景我们确实狠需要,当我们使用RealmChangeListener的时候,RealmChangeListener会通知我们两次,一次是查询数据库完成的,一次是更新的,但是,我们并不需要。因此,大家要做好处理。
6. 数据库版本迁移的问题
从realm文档来看,数据库版本迁移不复杂,但是工作量较大,我们需要知道每次实体类的变更,事实上,我们要做的可能更多,我这里就不模拟迁移了,只给出上次迁移遇到的问题及结果。
新加字段问题
当我们新加字段的时候,如果没有@Required注解,那么我们需要设置.setNullable(字段,false)
,没错,就是false。按理来说,我们不是应该为true么?但是,通过追源码得知。设置true,会抛出throw new IllegalStateException("Field is already required: " + fieldName);
但是要注意,新加的类不需要setnullable
上周四血的教训!!!
7 总结
由于使用时间较短,暂时只发现这个。最后,选择realm,一定要考虑清楚是否真的需要,是否想好了怎么处理这些问题。
- 说说Realm在Android上的坑
- Realm在android的应用
- Android上替代SQLite的选择:Realm
- 说说Android上的断点续传下载
- 说说Android上的断点续传下载
- 说说Android上的断点续传下载
- 说说Android上的断点续传下载
- 说说Android上的断点续传下载
- 说说Android上的断点续传下载
- 说说Android上的断点续传下载
- 说说Android上的断点续传下载
- Realm 在Android中应用
- reactnative Realm Android 关联不上realm库
- 说说我自己在window10上配置React Native 的过程和所遇到的坑
- Android ReactNative使用realm走过的坑(一)-Missing Realm constructor
- Android数据库Realm的第一次
- Android Realm数据库的使用
- 说说最近我在S5pv210 wince/android系统上调试VGA 1440*900/1280*720/1280*1024遇到的情况
- 关于hashMap遍历方法,用Iterator对hashMap进行遍历
- CSS根据屏幕分辨率宽度自动适应的办法
- 指针数组和数组指针的详细解答
- 安卓Andriod使用入门(七)【Android日历控件】
- python中的__name__ =="__main__"是什么意思呢
- 说说Realm在Android上的坑
- 小影
- max(X,Y),min(X,Y)的期望求解
- Android动画
- HDFS ZKFC自动切换原理分析
- 【C语言】运算符号详细说明
- 支持向量机
- git pull时报错fatal: Could not read from remote repository.
- 最短路-弗洛伊德算法