没有经过修改的greendao的数据库文件储存路径是默认的 data/data/包名/。。。文件夹下,这种情况下当app重装升级或者卸载之后,原来保存在默认路径下的数据库文件就会都被删除,想要在重装之后继续拥有原来的数据,就必须讲数据库文件保存在SD卡路径下,这样数据就不会在重装时被删除了
而且存储在默认路径下 不root是无法查看到数据库文件的 所以,改!!
且看修改方法
1.我们可以通过重写Context的
getDatabasePath(String name)、
openOrCreateDatabase(String name, int mode, CursorFactory factory)、openOrCreateDatabase(String name, int mode, CursorFactory factory, DatabaseErrorHandler errorHandler)
等三个方法来修改SQLite文件的存储路径。
public class GreenDaoContext extends ContextWrapper {
private Context mContext;
public GreenDaoContext() {
super(MyApplication.getContext());
this.mContext = MyApplication.getContext();
}
/**
* 获得数据库路径,如果不存在,则创建对象对象
*
* @param name
*/
@Override
public File getDatabasePath(String name) {
// 判断是否存在sd卡
boolean sdExist = android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState());
if (!sdExist) {// 如果不存在,
Log.e("test", "SD卡不存在,请加载SD卡");
return null;
} else {// 如果存在
// 获取sd卡路径
String dbDir = android.os.Environment.getExternalStorageDirectory().getAbsolutePath();
dbDir += "/Android";// 数据库所在目录
String dbPath = dbDir + "/" + name;// 数据库路径
// Log.e("test", "getDatabasePath: ------数据库路径= " + dbPath );
// 判断目录是否存在,不存在则创建该目录
File dirFile = new File(dbDir);
if (!dirFile.exists()) {
dirFile.mkdirs();
// Log.e("test", "getDatabasePath: --------创建了文件夹" );
}
// 数据库文件是否创建成功
boolean isFileCreateSuccess = false;
// 判断文件是否存在,不存在则创建该文件
File dbFile = new File(dbPath);
Log.e("test", "getDatabasePath: db文件已经存在了吗?"+dbFile.exists() );
if (!dbFile.exists()) {
try {
// Log.e("test", "getDatabasePath: ---------开始创建db文件" );
isFileCreateSuccess = dbFile.createNewFile();// 创建文件
// Log.e("test", "getDatabasePath: --------创建了文件,创建成功吗?" + isFileCreateSuccess);
} catch (IOException e) {
// Log.e("test", "getDatabasePath: -----------创建失败 捕捉到了一个sb异常啊,是啥?" + e.toString());
e.printStackTrace();
}
} else{
isFileCreateSuccess = true;
}
// 返回数据库文件对象
// Log.e("test", "getDatabasePath: --------文件是否创建成功?" + isFileCreateSuccess);
if (isFileCreateSuccess) {
return dbFile;
} else {
// Log.e("test", "getDatabasePath: ---------name ="+name );
return super.getDatabasePath(name);
}
}
}
/**
* 重载这个方法,是用来打开SD卡上的数据库的,android 2.3及以下会调用这个方法。
*
* @param name
* @param mode
* @param factory
*/
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) {
return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
}
/**
* Android 4.0会调用此方法获取数据库。
*
* @see android.content.ContextWrapper#openOrCreateDatabase(java.lang.String,
* int,
* android.database.sqlite.SQLiteDatabase.CursorFactory,
* android.database.DatabaseErrorHandler)
* @param name
* @param mode
* @param factory
* @param errorHandler
*/
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
}
}
2.重写好context类,再来一个helper类
public class GreenDaoHelper extends Application{
private GreenDaoHelper Instance;
private static DaoMaster daoMaster;
private static DaoSession daoSession;
public GreenDaoHelper getInstance() {
if (Instance == null) {
Instance = this;
}
return Instance;
}
/**
* 获取DaoMaster
*
* @param context
* @return
*/
public static DaoMaster getDaoMaster(Context context) {
if (daoMaster == null) {
ContextWrapper wrapper = new GreenDaoContext();
DaoMaster.OpenHelper helper = new DaoMaster.DevOpenHelper(wrapper,"test.db",null);
daoMaster = new DaoMaster(helper.getWritableDatabase()); //获取未加密的数据库
Log.e("test", "getDaoMaster: ------- 获取了数据库daoMaster");
}
if (daoMaster == null) {
Log.e("test", "getDaoMaster:-------------daoMaster还是空的啊 怎么搞的 " );
}
return daoMaster;
}
/**
* 获取DaoSession对象
*
* @param context
* @return
*/
public static DaoSession getDaoSession(Context context) {
if (daoSession == null) {
if (daoMaster == null) {
daoMaster = getDaoMaster(context);
}
if (daoMaster == null) {
Log.e("test", "getDaoSession: -------daoMaster是空的");
}
daoMaster.newSession();
}
return daoSession;
}
}
3.初始化数据库的方法
public class DBUtil {
public static DaoSession initDb(Context context) {
// 初始化数据库
DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(context, "laidianbao.db", null);
DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDb());
DaoSession daoSession = daoMaster.newSession();
return daoSession;
}
}
4.拿到daoSession
使用我们自定义的修改过路径的context类作为参数
DaoSession daoSession = DBUtil.initDb(new GreenDaoContext());
5.用daosession来进行数据库操作
daoSession.getMessageTemplateDao().insert(new MessageTemplate(null, type, content));
代码中的MessageTemplateDao是我自己写的实体类,各位根据自己的实际情况进行修改
这样基本上就没问题了
可是我当时因为粗心没有加权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
一直报GreenDaoContext 类中 重写的
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
}
return那行的空指针,WTF???? 我想了很久啊 最后真的是骂娘了
好啦,所以还是要细心点。
欢迎各位留言交流,共同进步