在项目中遇到这样的问题,数据库使用的 GreenDao, 两个 Activity, 分别添加同一个 Fragment, 查本地数据库,实体类中有一个是否选中状态的字段是不保存到数据库的,@transient 标记的,发现会出现这样的现象:在 Activity1 中的 Fragment 查出来,第一个位置选中,到 Activity2 中的 Fragment 查出来的第一个位置也是选中的,what???
两个 Activity 分别 new Fragment, 这是在两个 Fragment 对象中的,最后 debug 跟踪到原来是在 Activity2 中数据库查出来的数据就是选中的,脑子里闪现出难道是 GreenDao 有缓存,于是搜索 “GreenDao 缓存”,果然是有,网上给出的清除缓存的方式就是调 daoSession.clear(), 这样的话不是把所有的表缓存都给清了吗,怎么让只是这个查询不缓存呢,看下 daoSession.clear() 里面做了什么
public void clear() {
***DaoConfig.getIdentityScope().clear();
***DaoConfig.getIdentityScope().clear();
***DaoConfig.getIdentityScope().clear();
}
可以看到清除的就是 DaoConfig 的 identityScope,下面看下这个做了什么
public final class DaoConfig implements Cloneable {
//...
private IdentityScope<?, ?> identityScope;
//...
// identityScope 在这里被赋值
@SuppressWarnings("rawtypes")
public void initIdentityScope(IdentityScopeType type) {
if (type == IdentityScopeType.None) {
// 当 type 是 IdentityScopeType.None 时就没有缓存了
identityScope = null;
} else if (type == IdentityScopeType.Session) {
if (keyIsNumeric) {
identityScope = new IdentityScopeLong();
} else {
identityScope = new IdentityScopeObject();
}
} else {
throw new IllegalArgumentException("Unsupported type: " + type);
}
}
}
设置 identityScope 是在 new Session 时传的,自动生成的 DaoMaster 类有两个 newSession 方法
public class DaoMaster extends AbstractDaoMaster {
//...
public DaoSession newSession() {
return new DaoSession(db, IdentityScopeType.Session, daoConfigMap);
}
public DaoSession newSession(IdentityScopeType type) {
return new DaoSession(db, type, daoConfigMap);
}
//...
}
所以只要在 newSession 时传 IdentityScopeType.None 就可以不使用缓存了。
当然,这次遇到的问题是查出来的状态需要是不选中的,也可以再查出来之后是选中状态的话进行修改,具体就要看具体问题适合哪种解决方式了。