Android:自定义Sqlite数据库路径

默认的sqlite数据库是放在/data/data/database目录下的,今天看腾讯云IM的demo发现再该路径下找不到它存放消息的数据库,找了下后发现居然是放在/data/data/files目录下的,虽然不知道为什么要放到这个目录,不过仔细想了下突然发觉假如把数据库放到非data目录下的话,就可以不借助contentprovider之类的方式实现跨应用访问数据库了,虽然安全性会降低,但在部分场景下还是会有所作用的。

阅读下了SqliteOpenHelper的源码,和数据库路径相关部分如下。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

public SQLiteDatabase getWritableDatabase() {

        synchronized (this) {

            return getDatabaseLocked(true);

        }

    }

 

     

    public SQLiteDatabase getReadableDatabase() {

        synchronized (this) {

            return getDatabaseLocked(false);

        }

    }

 

private SQLiteDatabase getDatabaseLocked(boolean writable) {

        if (mDatabase != null) {

            if (!mDatabase.isOpen()) {

                // Darn!  The user closed the database by calling mDatabase.close().

                mDatabase = null;

            else if (!writable || !mDatabase.isReadOnly()) {

                // The database is already open for business.

                return mDatabase;

            }

        }

 

        if (mIsInitializing) {

            throw new IllegalStateException("getDatabase called recursively");

        }

 

        SQLiteDatabase db = mDatabase;

        try {

            mIsInitializing = true;

 

            if (db != null) {

                if (writable && db.isReadOnly()) {

                    db.reopenReadWrite();

                }

            else if (mName == null) {

                db = SQLiteDatabase.create(null);

            else {

                try {

                    if (DEBUG_STRICT_READONLY && !writable) {

                       String path = mContext.getDatabasePath(mName).getPath()

                        db = SQLiteDatabase.openDatabase(path, mFactory,

                                SQLiteDatabase.OPEN_READONLY, mErrorHandler);

                    else {

                        db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ?

                                Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0,

                                mFactory, mErrorHandler);

                    }

                catch (SQLiteException ex) {

                    if (writable) {

                        throw ex;

                    }

                    Log.e(TAG, "Couldn't open " + mName

                            " for writing (will try read-only):", ex);

                    final String path = mContext.getDatabasePath(mName).getPath();

                    db = SQLiteDatabase.openDatabase(path, mFactory,

                            SQLiteDatabase.OPEN_READONLY, mErrorHandler);

                }

            }

            ........

  其实是调用了mContext的getDataBasePath方法,这个方法是在ContextImpl中实现的,再看下源码

复制代码

@Override
    public File getDatabasePath(String name) {
        return validateFilePath(name, false);
    }

private File validateFilePath(String name, boolean createDirectory) {
        File dir;
        File f;

        if (name.charAt(0) == File.separatorChar) {
            String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
            dir = new File(dirPath);
            name = name.substring(name.lastIndexOf(File.separatorChar));
            f = new File(dir, name);
        } else {
            dir = getDatabasesDir();
            f = makeFilename(dir, name);
        }

        if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
            FileUtils.setPermissions(dir.getPath(),
                FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
                -1, -1);
        }

        return f;
    }

复制代码

好吧,原来这么简单,原来Android本身已经实现了自定义路径的方法了,只要传入的path的第一个字符为"/"就行了。

总结下就一句话,只要传入自定义路径的完整路径就好了。。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值