Android中存储目录认识

Posted 笪笠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android中存储目录认识相关的知识,希望对你有一定的参考价值。

1、存储基本认识

参考自:https://blog.csdn.net/u010937230/article/details/73303034

其他:

(1)存储权限:应用对内部存储和外部存储私有目录读写不需要申请权限,对外部存储的公有目录读写需要获取android.permission.READ_EXTERNAL_STORAGE和android.permission.WRITE_EXTERNAL_STORAGE权限,之后才能进行Environment.getExternalxxxxx()相关目录的读写,而这两个权限在安卓10及以后的版本中将逐渐收紧。

(2)清除数据: 表示清除内部存储和外部存储私有目录下的所有文件

清除缓存:表示清除getCacheDir()和getExternalCacheDir()两个目录下的文件。

应用卸载:应用卸载后会清除数据, 外部存储下除私有目录外,其他目录都不能通过清除数据和清除缓存来删除残留文件,这也是应用卸载后文件残留的原因。

(3)应用双开:应用双开的情况下, 上述目录会将目录中的0替换为对应的数字, 该数字与手机厂商有关,如将/data/user/0/com.example.test/替换为/data/user/999/com.example.test/

2、五种存储方法存储目录分析

2.1、SharedPreferences存储

​ 通常使用如下代码获取SharedPreferences实例:

SharedPreferences preferences = context.getSharedPreferences("test", MODE_PRIVATE);

getSharedPreferences是Context类的一个抽象方法,其具体实现在android.app.ContextImpl类中:

    @Override
    public SharedPreferences getSharedPreferences(String name, int mode) {
        // At least one application in the world actually passes in a null
        // name.  This happened to work because when we generated the file name
        // we would stringify it to "null.xml".  Nice.
        if (mPackageInfo.getApplicationInfo().targetSdkVersion <
                Build.VERSION_CODES.KITKAT) {
            if (name == null) {
                name = "null";
            }
        }

        File file;
        synchronized (ContextImpl.class) {
            if (mSharedPrefsPaths == null) {
                mSharedPrefsPaths = new ArrayMap<>();
            }
            file = mSharedPrefsPaths.get(name);
            if (file == null) {
                file = getSharedPreferencesPath(name);
                mSharedPrefsPaths.put(name, file);
            }
        }
        return getSharedPreferences(file, mode);
    }
    
    public File getSharedPreferencesPath(String name) {
        return makeFilename(getPreferencesDir(), name + ".xml");
    }
    
    private File getPreferencesDir() {
        synchronized (mSync) {
            if (mPreferencesDir == null) {
                mPreferencesDir = new File(getDataDir(), "shared_prefs");
            }
            return ensurePrivateDirExists(mPreferencesDir);
        }
    }

​ 于是对名称为test的SharedPreferences, 其存储文件为test.xml, 存储目录为Context.getDataDir() + "shared_prefs", 是在内部存储中,即/data/user/0/com.example.test/shared_prefs。

2.2、SQLite数据库存储

​ 同样的,获取数据库文件的方法为public File getDatabasePath(String name),内部数据库文件目录为

    private File getDatabasesDir() {
        synchronized (mSync) {
            if (mDatabasesDir == null) {
                if ("android".equals(getPackageName())) {
                    mDatabasesDir = new File("/data/system");
                } else {
                    mDatabasesDir = new File(getDataDir(), "databases");
                }
            }
            return ensurePrivateDirExists(mDatabasesDir);
        }
    }

​ databases目录与shared_prefs目录同级。

2.3、文件存储

​ 文件存储目录主要看需求,应用私有数据应当存储在内部私有存储或者外部私有存储, 像媒体文件等可以存放在DCIM等目录。

2.4、Content Provider

​ Content Provider存储目录要看其所属的应用将相关的数据存放在哪个位置, 例如通讯录、通话记录、短信等数据,由对应的应用进行管理。

2.5、网络存储数据

​ 应用从网络中获取数据, 对应的数据由响应的服务器进行管理。

以上是关于Android中存储目录认识的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向使用 DB Browser 查看并修改 SQLite 数据库 ( 从 Android 应用数据目录中拷贝数据库文件 | 使用 DB Browser 工具查看数据块文件 )(代码片段

如何将本地存储中的 JSON 对象添加到 Android Studio 上的片段列表

我可以在 android studio 的片段上使用 Firebase 吗?

Android 上的 Kotlin:如何在片段中使用数据库中的 LiveData?

Android MVVM在哪里存储数据?

Android 逆向Android 进程注入工具开发 ( Visual Studio 开发 Android NDK 应用 | Visual Studio 中 SDK 和 NDK 安装位置 )(代码片段