Android中的文件存储问题

来源:互联网 发布:mac 软件安装桌面 编辑:程序博客网 时间:2024/06/06 20:52

Android Devicer Monitor 的常见问题

Android系统中主要提供了三种方式用于简单地实现数据持久化功能,即

1:文件存储

2:SharedPreferecne存储

3:数据库存储

这里主要就文件存储遇到的问题进行讨论。

我在学习第一行代码的文件存储时,发现data文件夹无法打开,还好多少了解一点Linux的知识,发现是对文件处理的权限不够的问题。于是在网上找到了相关的解决方案。

主要探讨了一下三方面问题:

1:Andorid Devicer Monitor 中File Explorer标签页什么也没有

2:File Explorer中的data文件无法打开。

3:File Explorer中的目标文件无法导出。

背景

最近在看《第一行代码》(第二版)中关于数据存储方案的介绍。数据的状态分为两种:瞬时状态和持久状态,一般保存在内存中的数据随着活动的关闭,数据也就销毁了,如果我们想保存这些数据,该怎么办呢?书中介绍了三种实现数据持久化的方法,分别是:文件存储,SharedPreference 存储以及数据库存储。

在学习第一种数据持久化方法文件存储的时候,我们通过 Context 类中的 openFileOutput() 方法创建一个指定了保存路径的 FileOutputStream 对象 out,然后用这个 out 对象去创建一个 OutputStreamWriter 对象,之后再用这个 OutputStreamWriter 对象创建一个 BufferedWriter 对象 writer,我们就是通过这个 writer 的 write() 方法向文件输出流写入我们想要保存的数据的。文件写入数据之后默认保存在 /data/data/(package name)/files 目录下。我们可以通过 Android Studio 中的 Android Device Monitor 去查看,Android Device Monitor 的打开方法如下所示。


打开 Android Device Monitor

问题1:设备 Offline, File Explorer 空空如也

打开 Android Device Monitor 之后,发现里面什么都没有,左边的面板上显示了一台模拟器,但出于 offline 状态,不对呀,我的模拟器命名开着的呀,它正在运行我刚刚写的 app 呢,怎么这里会显示离线状态呢?于是我试着 Google 去找解决方案。


File Explorer 不显示文件

在 StackOverflow 上我发现了有人和我一样也碰到了这个问题,不过底下的回答寥寥无几,我找到了一个最高赞的答案(其实也就一个赞....),如下图所示,他的意思是他也不明白其中的具体原理,但是他发现如果先打开 Android Device Monitor,然后再运行模拟器,就可以解决这个问题。


解决 File Explorer 不显示文件(from SO)

于是我按照这个方法尝试,先打开 Android Device Monitor,里面什么也没有,然后打开模拟器,随着模拟器的启动,Monitor 左侧面板出现了 offline 的模拟器,然后再相继启动很多服务,最后就显示为 online 了,如下图所示,这样我们就可以通过 Monitor 中的 File Explorer 标签访问模拟器中的文件了。


解决 File Explorer 不显示文件

问题2:File Explorer 中的文件无法访问

还记得刚刚说的吗,openFileOutput() 方法生成的文件存放在一个默认路径,即 /data/data/(package name)/files 下。由于我的包名是 com.knightaoko.filepersistencetest,所以在下文的叙述中,大家看到这个陌生的字符串不要惊讶,实际操作下替换成你自己的包名即可。(这期间还碰到个问题,好像 Android Device Monitor 不能和 Instant Run 同时运行,所以在此需要把 Instant Run 功能关闭,怎么关闭大家自行 Google,很简单的。)于是,下一步当然是打开这个路径了,找到 data,点击,没反应,再点击,还是没反应。又遇到问题了,我无法访问 data 目录,通过 Google 搜索,我知道了 File Explorer 中的每个文件和文件夹都是有访问权限的,如下图红框中标识的就是 data 文件夹的访问权限。


无权访问

访问权限是 drwxrwx--x,这玩意是什么意思呢?我相信,学过 Linux 的同学肯定一眼就知道这是什么意思。不知道也没关系,听我慢慢道来,这一个字符串一共有 10 个字符,第一个字符表示是文件夹还是目录,如果第 1 个字符是 d,则表示是文件夹。后面 9 个字符可以分为三组,第一组 rwx 表示所有者(user)对文件的访问权限,r 表示可读(read),w 表示可写(write),x 表示可被执行,- 表示没有该权限;第二组 rwx 表示组群(group)对文件的访问权限;第三组 --x 表示其他人(other)对文件的访问权限,可以看到,没有 r 和 w,说明 data 对其他人来说是不可读不可写的,怪不得我们不能打开它呢,那怎么办呢?于是我又网上搜啊搜,发现可以通过一定的方法修改文件的访问权限的,对,这个方法就是 adb shell。

adb shell 是 Android SDK 中的一个工具,你可以在你的 Android SDK 目录下的 platform-tools 找到它,下图就是我电脑上的该目录:


adb 所在目录

我们需要将这个目录添加到环境变量,为的是后面在命令行直接调用 adb 中的命令。比如在此我将 D:\AndroidSDK\platform-tools 添加到环境变量(具体怎么添加应该不用手把手教学了吧)后,运行 cmd 命令行,然后输入下面的命令。


通过 adb shell 获取文件访问权限
  • adb shell 是打开 adb 外壳程序。
  • su 是获取 root 权限,只有 root 权限才能修改文件的访问权限。
  • 底下一堆 chmod 777 是把对应的文件或文件夹的访问权限的后 9 位设置成 rwxrwxrwx,777 就三个二进制 111, 喝起来就是 111111111(9 个 1),即相当于把后 9 位访问权限都置 1,于是就成了 rwxrwxrwx,即所有用户都具有该文件的全部访问权限(妈妈再也不用担心我打不开 data 了…)。我们来看看结果:

修改后的文件访问权限

问题3:File Explorer 中的文件无法 pull(下载)

可以看到这些目录都能访问了,可以在包名目录下看到生成的 data 文件了,下一步我们想把这个文件复制到我们的电脑里,怎么操作呢?选中该文件,点击右上角的 pull 图标即可,如下图所示:


文件下载按钮

点击之后,选好保存路径。结果我们发现文件并没有保存下来,在 Console 窗口还提示了错误:


文件下载出错

意思就是拉取文件失败,因为你无权进行该操作。又是一脸懵逼,怎么办?还能怎么办,继续 Google 呗!这里我找了很久,终于发现了解决方案:adb root 。没错,在命令行输入这条语句,完美解决!(注意是在 windows 下的命令行,而不是 adb shell 里,当然前提是你添加了 adb 的目录到你的环境变量里)


通过 adb root 获取文件下载权限

然后我们再来 pull 一下,卧槽,崩溃了,又发现问题了:Failed to pull selection。


文件下载再次出错

怎么办?OK,继续 Google,在 StackOverflow 里找到了一个高赞的解决方法:


重新选择模拟器(from SO)

什么意思?重新选择一下 Android Device Monitor 左侧面板的设备即可,没错!就是把下图红框中国的玩意儿点一下。


重新选择模拟器

好了,我们再找到刚刚那个要拷贝的文件,pull 一下,卧槽!!成功了,真是踏破铁鞋无觅处,得来全得靠姑姑(谷歌)。

顺便无耻的把大佬的总结也转载一下。大笑大笑

总结

总结一下吧,初次使用 Android Device Monitor,本来只是用来辅助学习 SQLite,结果一上午碰到一大堆问题,总算都一一解决了,在此总结一下。

  1. Android Device Monitor 要在模拟器运行之前就打开,这样才不会出现模拟器设备 offline 的问题。

  2. Android Device Monitor 和 Instant Run 貌似有冲突,在用 Android Device Monitor 时关闭 Instant Run 功能。我相信还有更好的解决方法,不然打开一个大一点的 APP,不能同时用这两个功能,那多影响效率啊。只是我目前还处于学习阶段,上述方案能解决我当前的问题,不影响我进一步学习,那它就是 OK 的。

  3. 操作 Android Device Monitor 时,应该默认把你当做其他人(other)对待,所以你对文件的访问权限很受限制。解决方法是在命令行中,通过在 adb shell 里获取 root 权限,并更改相应文件的访问权限,当然记得将 adb 所在目录添加进环境变量。

  4. 能访问了但是不能下载也是很麻烦的事,通过在命令行运行 adb root 获取文件的下载权限

  5. 通过上述操作之后,就能正常使用 Android Device Monitor 进行文件管理了。但不幸的是,当你重启模拟器,或启动另一台模拟器时,这些配置又得重新来过,否则你还是无法访问和下载模拟器中的文件。这个问题的根源在于权限二字,问题不是不能获取权限(通过 adb shell 可以获取 root 权限),而在于获取权限太麻烦了,希望后续版本的 Android Studio 可以直接在 Android Device Monitor 的 GUI 中设置相应获取权限的命令,使得广大 Android 开发者对模拟器中的文件操作更有效率。


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 5个月孩子厌奶怎么办 怀孕后特别不爱吃水果怎么办 宝宝吃了无比滴怎么办 婴儿上火怎么办吃什么可以去火 肚子胀怎么办最快的方法 40天婴儿拉水怎么办 8个月宝宝坐不稳怎么办 宝宝段奶不吃奶粉怎么办 3个月宝宝头睡偏了怎么办 2个月婴儿抱着睡怎么办 两个半月的宝宝睡眠少怎么办 七个月宝宝不愿意坐怎么办 一个多月的宝宝老是哭闹怎么办 宝宝头老往后仰怎么办 8个月宝宝不会爬怎么办 孩子个头长得慢怎么办 宝宝个头长得慢怎么办 婴儿个头长得慢怎么办 11个月宝宝认生怎么办 3个月宝宝认人怎么办 3个月的宝宝认生怎么办 两个月的宝宝睡觉一惊一惊怎么办 六个月宝宝不喜欢喝水怎么办 三岁宝宝尿多怎么办 一岁的宝宝尿少怎么办 一岁宝宝尿黄怎么办 三岁宝宝尿黄怎么办 5个月宝宝认生怎么办 3岁宝宝怕生胆小怎么办 2岁宝宝怕生胆小怎么办 1岁半宝宝认生怎么办 宝宝认人一直哭怎么办 七个月宝宝认人怎么办 一个月宝宝认人怎么办 2个多月宝宝认人怎么办 婴儿认人一直哭怎么办 六个月宝宝认人怎么办 十一个月宝宝断奶后辅食怎么办 6个月宝宝不会坐怎么办 7个月宝宝坐不住怎么办 三个月宝宝白天闹觉怎么办