android高级之旅 (十二) 修改greendao数据库框架的储存路径

没有经过修改的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???? 我想了很久啊 最后真的是骂娘了

好啦,所以还是要细心点。

欢迎各位留言交流,共同进步

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值