Android 各种路径详细说明
存储分类:
内部存储路径,
内部缓存存储路径,
外部存储路径,
外部缓存存储路径
在有些手机上内部划出一个内部的sdcard路径和内部存储路径,当有sdcard时候,就有了六个路径
内部存储空间中的应用私有目录
对于设备中每一个安装的 App,系统都会在内部存储空间的 data/data 目录下以应用包名为名字自动创建与之对应的文件夹。这个文件夹用于 App 中的 WebView 缓存页面信息,SharedPreferences 和 SQLiteDatabase 持久化应用相关数据等。
对于没有 Root 过的手机,普通用户是无法查看 data/data 目录内容的。不过开发人员可以使用模拟器调试应用,并通过 DDMS(Dalvik Debug Monitor Server)提供的 File Explorer 工具查看模拟器设备的存储空间。
用户卸载 App 时,系统自动删除 data/data 目录下对应包名的文件夹及其内容
- context.getCacheDir()
这个目录和getFilesDir()目录最大的不同在于:当安卓设备的存储空间少,或者不够用的时候,系统会自动删除这个目录下的文件。
- context.getFilesDir()
当应用被移动到外部存储设备的时候,文件的绝对路径也是变化的,所以建议当数据存储到这个目录的时候,用相对路径。系统提供的访问此路径文件的方法是:context.openFileOutput(String,int);context.openFileInput(String name);
内部存储空间不需要申请权限
- context.deleteFile
外部存储空间中的应用私有目录
考虑内部存储空间容量有限,(官方建议是,超过1MB的文件,建议存储到getExternalCacheDir()目录下)普通用户不能直接直观地查看目录文件等其他原因,Android 在外部存储空间中也提供有特殊目录供应用存放私有文件,文件路径为:
/storage/emulated/0/Android/data/包名
备注:一般设备都有内置 SD 卡,同时也提供外部 SD 卡拓展,可能对应路径的目录名有所差异。
值得注意的是,与内部存储空间的应用私有目录不同的是:
- 第一,默认情况下,系统并不会自动创建外部存储空间的应用私有目录。只有在应用需要的时候,开发人员通过 SDK 提供的 API 创建该目录文件夹和操作文件夹内容。
- 第二,自 Android 7.0 开始,系统对应用私有目录的访问权限进一步限制。其他 App 无法通过 file:// 这种形式的 Uri 直接读写该目录下的文件内容,而是通过 FileProvider 访问。
- 第三,宿主 App 可以直接读写内部存储空间中的应用私有目录;而在 4.4 版本开始,宿主 App 才可以直接读写外部存储空间中的应用私有目录,使开发人员无需在 Manifest 文件中或者动态申请外部存储空间的文件读写权限。
而相同点在于:同属于应用私有目录,当用户卸载 App 时,系统也会自动删除外部存储空间下的对应 App 私有目录文件夹及其内容。
只有手机系统使用的是虚拟外部存储(虚拟SD卡,现在绝大多数的手机,都不用外挂物理SD卡了)的时候,
才可以在卸载应用的同时,自动删除该目录下的文件,如果是之前的物理存储(物理SD卡)则不会自动删除该目录,及目录下的文件。
Android SDK 中也提供有便捷的 API 供开发人员直接操作外部存储空间下的应用私有目录:
- getExternalFilesDir()
- getExternalCacheDir()
当然,也可以通过 Environment 类间接操作,只不过需要向用户申请操作权限
Environment.getExternalStorageDirectory();
类似于 File 和 Cache 默认分类目录,开发人员也可以在应用私有目录中创建属于自己的自定义目录,方便于分类存储应用相关文件。
关于Environment.getExternalStorageDirectory();做一些说明:
应用外部存储空间(数据文件非私有,可以被手机的系统程序访问(如MP3格式的文件,会被手机系统检索出来),同样,该目录下的文件,所有的APP程序也都是可以访问的,)
注意:外部存储空间可能处于不可访问状态,或者已经被移除状态,或者存储空间损坏无法访问等问题。可以通过getExternalStorageState()这个方法来判断外部存储空间的状态。
注:在该目录下读写文件,需要获取读写权限
该目录下的文件,这个目录是用户进行操作的一个根目录,进入二级目录可以通过
getExternalFilesDirs(String), getExternalCacheDirs(), and getExternalMediaDirs().这些方法
官方建议,不要直接使用该目录,为了避免污染用户的根命名空间,应用私有的数据,应该放在 Context.getExternalFilesDir目录下
其他的可以被分享的文件,可以放在getExternalStoragePublicDirectory(String).目录下
值得注意的一点是,对于外部存储空间下的应用私有目录文件,由于普通用户可以自由修改和删除,开发人员在使用时,一定要做好判空处理和异常捕获,防止应用崩溃退出!
外部存储空间中的公共目录
通常来说,应用涉及到的持久化数据分为两类:应用相关数据和应用无关数据。前者是指专供宿主 App 使用的数据信息,比如一些应用的配置信息,数据库信息,缓存文件等。当应用被卸载,这些信息也应该被随之删除,避免存储空间产生不必要的占用。
相对而言,后者更偏向于这类信息:当应用被卸载,用户仍然希望保留于设备当中的信息。常见如,拍照类应用的图片文件,用户是使用浏览器手动下载的文件等。
显然,无论是内部存储空间,还是外部储存空间,上述两个应用私有目录由于其特有的生命周期(随着应用卸载而自动清除)只适合存储应用相关数据。
或者从访问权限上来说,应用无关数据应该是宿主应用希望与其他应用共享这些数据的,应该存放在外部存储空间的公共目录文件夹下。
外部存储空间已经为用户默认分类出一些公共目录。开发人员可以通过 Environment 类提供的方法直接获取相应目录的绝对路径,传递不同的 type 参数类型即可:
Environment.getExternalStoragePublicDirectory(String type);
Envinonment 类提供诸多 type 参数的常量,比如:
- DIRECTORY_MUSIC:Music
- DIRECTORY_MOVIES:Movies
- DIRECTORY_PICTURES:Pictures
- DIRECTORY_DOWNLOADS:Download
等等,以第一个常量为例,音乐类别的公共目录绝对路径为:/storage/emulated/0/Music。如果你使用文件管理器打开设备的外部存储空间的话,均可以看到这些公共目录文件夹。
面对如此诸多的默认类别,开发人员在保存自己应用的公共文件时,也要养成良好的习惯,将要保存的数据分门别类地保存在不同公共目录下。当然,你也可以在公共目录下再次创建属于自己应用的目录,便于管理。
注意:访问外部存储空间时记得申请读写权限!
外部存储空间中的其他目录一般来说,利用两种应用私有目录和公共目录便能够存储应用中需要保存的数据和文件。如果这些还不够的话,那一定是你的开发姿势不对。在 Code Review 的前提下,如果还是不够的话,还可以在外部存储空间自由创建其他目录,通过这个方式获取外部存储空间的绝对路径,然后操作文件:
Environment.getExternalStorageDirectory();
小结
* 记住外部是data/data/包名目录,外部是Android/data/包名,应用私有目录,卸载app,系统自动删除应用私有目录,内部外部,是从系统的角度来说的 *
使用应用私有目录保存应用相关数据,使用公共目录保存应用无关数据(共享数据)。无论哪种情况,都需要做好数据分类保存,便于清除等统一管理。随便打开手机上的几个应用,不难发现,很多应用都包含一个清理缓存的功能。事实上,开发人员清理的就是应用相关数据,也就是应用私有目录下的文件。
考虑到外部存储空间上的内容可能被用户手动删除,或者卸载拓展 SD 卡等不可控因素,操作前记得使用 Environment 类提供的 API 方法判断容量是否充足、文件是否存在等情况,做好异常捕获,减少应用崩溃率。相信这一定是一个良好的习惯
存储路径和缓存存储路径的区别
1. 缓存路径一般用于存放一些缓存数据,当程序删除的时候,缓存文件夹也会随之删除,避免了程序在卸载之后残留大量文件。
2. 内部缓存路径和外部缓存路径也有所区别,当系统的内存空间紧张时,内部缓存路径下的文件会被删除,但是没有一个严格的标准保障,应该对这些缓存文件占用的最大存储空间设定个最大值,当实际超过这个值时,要对这些缓存文件做相应的清理工作 。但是系统不会观察外部缓存路径下是否超出大小,要自己去做文件清理机制。
3. 内部缓存路径默认别的程序不能访问文件,所以一些私密的数据,别的应用是访问不了的,如果需要系统或者其他应用访问,可以通过修改openFileOutput()下的int mode参数让别的应用也可以访问。
* 内部缓存路径 *
内部的 /data/data/一般是看不到的,除非root
清除缓存 context.getCacheDir()
模拟器:内部缓存路径:/data/data/com.mocn.testin/cache/内部缓存路径.png
Nexus5:内部缓存路径:/data/user/0/com.mocn.testin/cache/内部缓存路径.png
log
04-09 00:03:23.821 13714-13714/com.example.bafc.myapplication E/mrpeng: Environment.getRootDirectory()=:/system
04-09 00:03:23.821 13714-13714/com.example.bafc.myapplication E/mrpeng: Environment.getDataDirectory()=:/data
04-09 00:03:23.821 13714-13714/com.example.bafc.myapplication I/mrpeng: Environment.getDataDirectory().getAbsolutePath()/data
04-09 00:03:23.821 13714-13714/com.example.bafc.myapplication E/mrpeng: Environment.getDownloadCacheDirectory()=:/cache
04-09 00:03:23.821 13714-13714/com.example.bafc.myapplication E/mrpeng: Environment.getExternalStorageDirectory()=:/storage/emulated/0
04-09 00:03:23.821 13714-13714/com.example.bafc.myapplication E/mrpeng: Environment.getExternalStoragePublicDirectory()=:/storage/emulated/0/Pictures
04-09 00:03:23.821 13714-13714/com.example.bafc.myapplication E/mrpeng: Environment.getExternalStorageState()=:mounted
04-09 00:03:23.821 13714-13714/com.example.bafc.myapplication E/mrpeng: Environment.isExternalStorageEmulated()=:true
04-09 00:03:23.821 13714-13714/com.example.bafc.myapplication E/mrpeng: Environment.isExternalStorageRemovable()=</span>:false
04-09 00:03:23.821 13714-13714/com.example.bafc.myapplication E/mrpeng: context.getFilesDir()=:/data/data/com.example.bafc.myapplication/files
04-09 00:03:23.821 13714-13714/com.example.bafc.myapplication E/mrpeng: context.getCacheDir()=:/data/data/com.example.bafc.myapplication/cache
04-09 00:03:23.841 13714-13714/com.example.bafc.myapplication E/mrpeng: context.getExternalFilesDir()=:/storage/emulated/0/Android/data/com.example.bafc.myapplication/files/Movies
04-09 00:03:23.841 13714-13714/com.example.bafc.myapplication E/mrpeng: context.getExternalCacheDir()=:/storage/emulated/0/Android/data/com.example.bafc.myapplication/cache
04-09 00:03:23.841 13714-13714/com.example.bafc.myapplication E/mrpeng: context.getPackageResourcePath()=:/data/app/com.example.bafc.myapplication-2.apk
04-09 00:03:23.841 13714-13714/com.example.bafc.myapplication E/mrpeng: context.getDatabasePath("mufeng")=:/data/data/com.example.bafc.myapplication/databases/mufeng
Android 各种路径详细说明的更多相关文章
- Android BLE蓝牙详细解读
代码地址如下:http://www.demodashi.com/demo/15062.html 随着物联网时代的到来,越来越多的智能硬件设备开始流行起来,比如智能手环.心率检测仪.以及各式各样的智能家 ...
- android的logcat详细用法!
from://http://www.miui.com/article-272-1.html [技术交流]android的logcat详细用法! logcat是Android中一个命令行工具,可以用于得 ...
- Android SQLite 数据库详细介绍
Android SQLite 数据库详细介绍 我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用 ...
- [转] 关于 Eclipse 导出 Android项目 JavaDoc 详细过程
关于Eclipse 导出JavaDoc过程中,遇到的问题 ,google 了一下 ,网友们 总说不一 ,最终 还是 搞定了 现在分享给大家 希望对大家有所帮助 用Eclipse默认的 JavaDoc需 ...
- Android开发:修改eclipse里的Android虚拟机路径
一.发现问题: 今天打开电脑发现C盘缩了不少,这才意识到:eclipse里配置的安卓虚拟机默认放在了C盘里. 当然,在不同的电脑上可能路径有所不同,我的默认路径是:C:\Users\lenovo\.a ...
- Android存储路径你了解多少?
在了解存储路径之前,先来看看Android QQ的文件管理界面,了解一下QQ的数据文件路径来源,到底是来源于什么地方? 手Q文件管理对应存储目录 我的文件:是指放在QQ指定目录下的文件:/tencen ...
- katalon设置Android SDK路径
本文链接:https://blog.csdn.net/feiniao8651/article/details/82809147文章允许转载,请注明来源:https://blog.csdn.net/fe ...
- android的logcat详细用法
Android日志系统提供了记录和查看系统调试信息的功能.日志都是从各种软件和一些系统的缓冲区中记录下来的,缓冲区可以通过 logcat 命 令来查看和使用. 使用logcat命令 你可以用 logc ...
- [zz]android的logcat详细用法
Android日志系统提供了记录和查看系统调试信息的功能.日志都是从各种软件和一些系统的缓冲区中记录下来的,缓冲区可以通过 logcat 命令来查看和使用. 一.使用logcat命令的目的: ...
随机推荐
- sublime test3 乱码问题的解决
1.下载ConvertToUTF8插件,地址:http://pan.baidu.com/s/1bnvVd2R 2.按Ctrl+Shift+P打开命令行,输入Install Package,回车,然后继 ...
- 【51nod 1100】斜率最大
Description 平面上有N个点,任意2个点确定一条直线,求出所有这些直线中,斜率最大的那条直线所通过的两个点. (点的编号为1-N,如果有多条直线斜率相等,则输出所有结果,按照点的X轴坐标 ...
- hashMap源码分析1--翻译
* Hash table based implementation of the <tt>Map</tt> interface. This* implementation pr ...
- 简单linux命令1
1. cat 一次显示整个文件: cat filename 从键盘创建一个文件: cat> filename 将文件合并: cat file1 file2 > filename 2. ...
- 关于利用PHP访问MySql数据库的逻辑操作以及增删改查实例操作
PHP访问MySql数据库 <?php //造连接对象$db = new MySQLi("localhost","root","",& ...
- html5 area实例
真实页面效果:就是一张图 html代码: <!DOCTYPE HTML> <html> <style> body{ padding:0px; margin:0px; ...
- Python转义字符&字符串运算符
Python转义字符 在需要在字符中使用特殊字符时,python用反斜杠(\)转义字符.如下表: 转义字符 描述 \(在行尾时) 续行符 \\ 反斜杠符号 \' 单引号 \" 双引号 \a ...
- t-sql对被除数为0&除数小于被除数结果为0&除法保留2位小数的处理
SELECT round(CAST(12 AS FLOAT)/nullif(13,0),2,1) FROM TB
- 《jQuery精品教程视频》-每天的复习笔记
第一天 //jquery:简单.粗暴 //jq和js的关系 //js是什么? js是一门编程语言 //jq仅仅是基于js的一个库,jq可理解为就是开发js的一个工具. //概念 //1. 为什么要学j ...
- 微信小程序获取手机验证码
一种比较常见的功能获取手机验证码 先看效果图: 其实这个功能实现起来很简单,主要就是调取第三方接口,拿到返回值验证的问题 直接上代码吧: wxml页面: <view class='changeI ...