Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 698|回复: 0

解决SQLite打开已有路径下的db问题

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-9-1 15:59:11 | 显示全部楼层 |阅读模式

    最近遇到的需要加载已有路径下(sd card下)db的问题,找了一下资料,以下是解决的方法,仅供参考(转载自eoe):

    SQLiteOpenHelper 是Android框架为我们提供的一个非常好的数据库打开、升级与关闭的工具类。但是这个工具类会自动把db文件创建到“ /data/data/com.*.*(package name)/” 目录下,这么做可能是与Android文件系统的设计思路有关。

    但 是在实战过程中,我们可能有各种原因需要自定义db文件路径(例如db文件较大放到sd卡更安全等等),相信很多人都遇到了这个需求,网上也有很多解决方 法,这些方法大多是抛弃Android框架为我们提供的SQLiteOpenHelper类,自己重头写一个DbHelper类完成自定义路径的数据库打 开关闭等。这么做虽然可以解决问题,但并不是一个最好的方法,因为自己写的DbHelper可靠性和功能自然难和google巨匠相。

     

    本文提出一种方法,通过继承和添加代码,并复用SQLiteOpenHelper的代码,来解决自定义db路径的问题。

    首 先我们来分析一下SQLiteOpenHelper的源代码。getReadableDatabase()和getWritableDatabase() 在内部都是调用getDatabaseLocked()。getDatabaseLocked()的源代码很容易理解,分析得知:

    • 如果以只读方式打开,是通过mContext.getDatabasePath(mName)来获取db文件的路径并使用SQLiteDatabase.openDatabase()直接打开数据库;
    • 如 果以读写方式打开,是通过mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ? Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0, mFactory, mErrorHandler)打开或创建数据库。

    所以我们需要改变mContext的行为。Android框架提供了一个ContextWrapper类,是Context的一个代理,可以通过继承的方式拉改变Context的行为,所以我们继承ContextWrapper,代码如下:

    class CustomPathDatabaseContext extends ContextWrapper{
        private String mDirPath;

      public CustomPathDatabaseContext(Context base, String dirPath) {

        super(base);

        this.mDirPath = dirPath;

      }
                   

      @Override

      public File getDatabasePath(String name) {

        File result = new File(mDirPath + File.separator + name);

        if (!result.getParentFile().exists()){

          result.getParentFile().mkdirs();

        }

        return result;

        }

        

      @Override

      public SQLiteDatabase openOrCreateDatabase(String name, int mode ,CursorFactory factory){

        return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), factory);

      }

      

      @Override

      public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory, DatabaseErrorHandler errorHandler){

        return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name).getAbsolutePath(), factory, errorHandler);

      }
      }

    上述代码很简单了,就不用多说明了吧,然后我们在继承SQLiteOpenHelper时这么写就可以了:

    class YourDbHelper extends SQLiteOpenHelper{

            public YourDbHelper(Context context, String name, CursorFactory factory,
                            int version) {
                    super(new CustomPathDatabaseContext(context, getDirPath()), name, factory, version);
            }

            /**
             * 获取db文件在sd卡的路径
             * @return
             */
            private static String getDirPath(){
                    //TODO 这里返回存放db的文件夹的绝对路径
                    return "";
            }
            
            @Override
            public void onCreate(SQLiteDatabase db) {
            }

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            }
            
      }

    如此一来,我们既可以自定义db文件路径,又可以复用SQLiteOpenHelper十分好用的功能了~

     

    另外需要注意的是,有些应 用可能是有一个已建好表的db文件放在assets中,应用运行时先判断db文件是否存在,如果不存在则从assets中复制到自定义路径。这种情况通常 都是在PC端使用SQLiteSpy诸如此类的工具写sql建表,使用这种方法的小伙伴们别忘了在建表时执行  PRAGMA schema_version = 1   这句sql(当然了版本号取决于您的需求) , 否则SQLiteOpenHelper还是会触发onCreate的~看了SQLiteOpenHelper什么时候触发onCreate的源码就明白怎么回事了~

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-12-22 02:31 , Processed in 0.051700 second(s), 28 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表