您当前的位置:首页 > 电脑百科 > 程序开发 > 移动端 > Android

Android开发者!好好管理你应用文件夹,别再乱用了

时间:2019-08-01 09:29:57  来源:  作者:


码个蛋(codeegg)第 698 次推文

作者: SpannerBear

原文: https://juejin.im/post/5d2c36f5e51d4556db694aa3

Android/ target=_blank class=infotextkey>安卓碎片化的问题,由来已久,这次来看一下文件储存碎片化的问题。到底要怎么去正确选择和管理文件存储呢?

为什么要管理文件?

Android手机一直以来被人诟病越用越卡,越用存储空间越少,经常有要靠各种清理App清理垃圾,到最后不得对手机进行双清,原因除了硬件老化和Android的底层实现问题之外,开发者对文件管理的忽视制造出大量无法清理的“垃圾”也是造成手机卡慢的原因之一。

Android的开放性给了开发者巨大的自由度,但自由不是让我们滥用权限和随意开发的借口,每一个开发者都应该注重细节,连曾经一片混乱的第三方推送都开始统一整合规范化了,如果你还在随意开发,不如现在开始,注重细节,提高用户的Android手机体验?

Android闪存

总所周知,Android手机存储分为两个部分:内部存储外部存储,内部存储一般是手机自带的存储空间,外部存储指外插SD卡提供的存储空间;随着手机发展,这两个存储的定义又有了一些些变化,新的手机不再有外插SD卡的概念,采取了内置闪存(eMMC、UFS等)的方式,所以内部存储和外部存储在新的Android手机上已经在同一个硬件上了。但为了兼容旧设备和让用户得到更好的体验,我们仍然需要管理好手机上内外存储的使用。

关于文件存储位置的api

做过文件相关管理的同学应该都曾经被android众多的文件api搞得一片混乱过,现在来理一理.我把应用操作的文件存储位置分为三个部分

  1. 应用内部存储私有文件目录

  2. 应用外部存储私有文件目录

  3. 公有目录

我们有两种api去获取这三个部分的存储位置,它们分别归属于Context和Environment。

 

Context

Context是应用的上下文,它用来获取与应用相关的文件目录,可以获取应用私有和应用公有目录,常用的api有(后面是所对应的路径):

1. Context#getCacheDir /data/user/0/cn.appname.xxx/cache
2. Context#getDir("spanner",MODE_PRIVATE) /data/user/0/cn.appname.xxx/app_spanner
3. Context#getFileDir /data/user/0/cn.appname.xxx/files
3. Context#getExternalCacheDir /storage/emulated/0/Android/data/cn.appname.xxx/cache
4. Context#getExternalFilesDir(Environment.DIRECTORY_PICTURES) /storage/emulated/0/Android/data/cn.appname.xxx/files/Pictures
Context#getExternalFilesDir /storage/emulated/0/Android/data/cn.appname.xxx/files
5. Context#getExternalMediaDirs /storage/emulated/0/Android/media/cn.appname.xxx

前两个是应用内部存储私有目录,后面4个都是应用外部存储私有文件目录。注意:/data/user/0/ 等同于 /data/data/

Environment

Environment和应用无关,它用于获取公有存储位置的文件目录,常用的api有:


 
1. Environment#getExternalStorageDirectory /storage/emulated/0
2. Environment#getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) /storage/emulated/0/DCIM
Environment#getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) /storage/emulated/0/Pictures
3. Environment#getDataDirectory /data
4. Environment#getDownloadCacheDirectory /data/cache
5. Environment#getRootDirectory /system
 

API的选用

 

到底什么时候要用什么api呢?

 

应用私有文件目录

应用私有目录由Context获取控制,分为内部存储外部存储,内部存储不需要申请文件读写权限也能够使用,外部存储需要权限(getetExternalCacheDir 和 getExternalFilesDir 这两个方法从4.4之后不再需要读写权限)。用户对app进行数据清理或卸载可以清理外部存储和内部存储下的所有文件目录。

内部存储

内部存储的文件夹其他应用和用户无法直接访问,可以用于存放敏感数据。

  • getCacheDir

    • 专门用于存放缓存数据。

    • 用户对app进行缓存清理的时候会清理缓存目录cache的数据,手机空间不足的时候系统也会对缓存目录内的数据进行清理。但尽管如此,开发者仍要管理好缓存数据特别是内部存储的缓存,避免缓存数据过大。

  • getFileDir

    • 可用于用于存放私有持久文件。

    • 非常适合用于存放app各种伴随app运行周期所需要的文件数据,它既不会因为手机存储空间不足而被清理,也不会因卸载app而遗留数据垃圾,并且它是私有的。

  • getDir(String name,int mode)

    • 归类存放私有文件。

    • 在内部私有目录下会创建一个名为app_name的文件夹,mode以前是可以设置文件夹私有(MODE_PRIVATE)和公有的(MODE_WORLD_READABLE、MODE_WORLD_WRITEABLE),但目前公有的mode都已经废弃,意味着这个api创建的文件夹已经完全私有,不能再共享出去了。

外部存储

在Android Q之前其他应用是可以访问修改外部存储的应用私有目录的,这个要注意。

使用外部存储之前一定要检查外部存储是否可用,因为旧设备不一定会有外部存储,新手机也不一定会给你读写权限,就算用户不给你权限,你的app也要运行啊,不然就不用你的了。

public static boolean isSDCardEnable {
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState);
}
  • getExternalCacheDir

    • 专门用于存放缓存数据。和内部存储的getCacheDir相似。

  • getExternalFilesDir(String type)

    • 归类存放公有文件。

    • 如果type不为的话在外部私有目录下创建返回一个名为type的文件夹,为直接返回外部私有根目录。如无特别需要,个人的做法是传入Environment的DIRECTORY常量进行文件夹创建。

    • 如果看完这篇你还不会选用api,那就把你应用杂七杂八的东西都放进去吧,文件至少不用东一件西一件的,卸载之后也能够被正确清理掉,不过也要控制好占用的存储空间。

  • getExternalMediaDirs

    • 可存放共享媒体文件。

    • 这个是在Android 5.0加入的api,创建和获取位于/sdcard/Android/media目录下的应用目录,该目录下的文件能够被其他应用访问和被MediaStore查询和获取。但目前较少开发者在使用这个api。

 

公有目录

获取公有目录要使用Environment的Api,它返回的目录全都是共享的公有目录。造成Android手机文件存储混乱的罪魁祸首!为数众多的无责任开发者在这里胡乱创建文件夹,乱起名、乱放文件,普通用户根本无法判断哪些文件夹、文件是有用的,卸载app之后留下庞大的无法清理的垃圾文件,导致手机空间不足。于是它们在Android Q被废弃了,但是Q之前还是能好好使用的,我认为要开始减少使用它们,更多地使用Context下的私有目录API。

  • getExternalStorageDirectory

    • 获取外部存储(SD卡)的根目录。使用getExternalStoragePublicDirectory(String)进行替代即可。

  • getExternalStoragePublicDirectory(String type)

    • 使用频率极高的api,返回在根目录下的名为type的文件夹,我把它分为两种用法:一种是传入Environment的DIRECTORY常量再创建子目录使用;一种是传入appPackageName或者易被识别归属的名称创建子目录使用。前者会比较通用,内容可以被各种工具app搜索发现(包括微信);后者算是私用,可以存放不跟随app生命的文件,即卸载后也可以保留。

    • Environment.DIRECTORY_DCIM是手机的相册,这个文件夹都是系统相关的app在用,存放相机拍摄的图片,手机截图之类的,不推荐开发者使用这个文件夹,避免混乱。值得一提的是淘宝有在使用这个文件夹,用于保存它的商品分享截图,这个位置的确可以避免被微信封杀~哈哈

    • Environment.DIRECTORY_PICTURES用于存放各种“正式的”图片,强烈建议在这里创建文件夹存放你想要被用户发现的图片,并且微信会扫描这个文件夹,让你的图片更容易分享。不过还。

    • Environment.DIRECTORY_DOWNLOADS可以用于存放app更新的apk等下载资源。

    • 其他几个比较少用就不介绍了。

适配Android Q

上面提到Environment的两个公有目录常用API在Android Q被废弃了,应用存储功能沙箱化,文件存放到沙箱外面要使用 DocumentFile,共享媒体文件要使用MediaStore进行,详细的适配已有其他开发者分享出来了,推荐一下这篇:Android Q 存储机制大变化(https://link.juejin.im/?target=https%3A%2F%2Ffeng.moe%2Farchives%2F47%2F

我很喜欢的承香墨影也出了篇适配指南,内容更加详细:Android Q 要来了,给你一份很"全面"的适配指南!(https://mp.weixin.qq.com/s/aiDMyAfAZvaYIHuIMLAlcg

结尾

最后说一下几个重要的事:

获取文件路径这件事永远不能写死某个路径,不存在SD卡怎么办呢?某个路径无法使用了怎么办呢?所以管理文件的时候必须要有存储策略。比如一个文件的保存地址获取方法里不能只有一个api,要保有兜底措施,如果我不能存在外部储存,那我就存在内部,保证app的功能正常运行。

这次的这里,希望看完这篇文章之后能够让你更了解如何管理手机文件夹。



Tags:Android开发   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
今天面试遇到同学说做过内存优化,于是我一般都会问那 Bitmap 的像素内存存在哪?大多数同学都回答在 java heap 里面,就比较尴尬,理论上你做内存优化,如果连图片这个内存大户内存...【详细内容】
2021-12-23  Tags: Android开发  点击:(8)  评论:(0)  加入收藏
对项目的基本介绍 1.整个框架主要是给MVVM框架使用的,自己写完interface接口后,通过自定义的注解就能自动生成接口方法 2.用Kotlin的Flow去代替Rxjava,因为我发现RxJava功能很...【详细内容】
2021-12-08  Tags: Android开发  点击:(17)  评论:(0)  加入收藏
前言在Android开发过程中,有些时候会根据需要引用别的项目到当前项目里面,而且以Module形式引用。所以本篇博文就来分享一下怎么以Module形式引用别的项目到当前项目中,方便开...【详细内容】
2021-12-07  Tags: Android开发  点击:(22)  评论:(0)  加入收藏
作者:fundroid这篇文章偏阅读一些,大家可以了解下 Android 的一些最新动向。每年9/10月份 Google 都会举行约为期2天的 Android Dev Summit,在活动上 Google 的技术专家们会分...【详细内容】
2021-11-30  Tags: Android开发  点击:(15)  评论:(0)  加入收藏
概述当Android应用程序需要访问设备上的敏感资源时,应用程序开发人员会使用权限模型。虽然该模型使用起来非常简单,但开发人员在使用权限时容易出错,从而导致安全漏洞。本文中,...【详细内容】
2021-09-07  Tags: Android开发  点击:(66)  评论:(0)  加入收藏
Zygote可以说是Android开发面试很高频的一道问题,但总有小伙伴在回答这道问题总不能让面试满意, 在这你就要搞清楚面试问你对Zygote的理解时,他最想听到的和其实想问的应该是哪...【详细内容】
2021-08-12  Tags: Android开发  点击:(104)  评论:(0)  加入收藏
目前市场中使用音视频技术的公司太多了,大到全民观看短视频,小到直播带货,每个国人的用手机的时间也被视频占据着国内的音视频行业可以划分为三类第一类 短视频抖音、快手、微...【详细内容】
2020-12-09  Tags: Android开发  点击:(131)  评论:(0)  加入收藏
一、Android JetPack——Google多么痛的领悟最近好几个小伙伴问我什么是Android JetPack,听说这个包好像有点牛,帅哥你会不?我心想什么鬼!Android JetPack这货不是一...【详细内容】
2020-09-14  Tags: Android开发  点击:(113)  评论:(0)  加入收藏
前言1、软件吃掉世界,而机器学习正吃掉软件在数据爆炸的时代,如何创建「智能系统」成为焦点。这些应用程序内所体现的智能技术,并非是将实用指令添加到代码中,而是可以让软件自...【详细内容】
2020-07-13  Tags: Android开发  点击:(76)  评论:(0)  加入收藏
1、使用优化过的数据容器。在Android framework下,建议使用优化过的数据容器比如:SparseArray,SparseBooleanArray,LongSparseArray。通用的HashMap实现的内存使用率非常的低,...【详细内容】
2020-04-26  Tags: Android开发  点击:(67)  评论:(0)  加入收藏
▌简易百科推荐
今天面试遇到同学说做过内存优化,于是我一般都会问那 Bitmap 的像素内存存在哪?大多数同学都回答在 java heap 里面,就比较尴尬,理论上你做内存优化,如果连图片这个内存大户内存...【详细内容】
2021-12-23  像程序那样思考    Tags:Android开发   点击:(8)  评论:(0)  加入收藏
Android logcat日志封装logcat痛点在Android开发中使用logcat非常频繁,logcat能帮我们定位问题,但是在日常使用中发现每次使用都需要传递tag,并且会遇到输出频率很高的log,在多...【详细内容】
2021-12-22  YuCoding    Tags:Android   点击:(8)  评论:(0)  加入收藏
对项目的基本介绍 1.整个框架主要是给MVVM框架使用的,自己写完interface接口后,通过自定义的注解就能自动生成接口方法 2.用Kotlin的Flow去代替Rxjava,因为我发现RxJava功能很...【详细内容】
2021-12-08  网易Leo    Tags:Android开发   点击:(17)  评论:(0)  加入收藏
前言在Android开发过程中,有些时候会根据需要引用别的项目到当前项目里面,而且以Module形式引用。所以本篇博文就来分享一下怎么以Module形式引用别的项目到当前项目中,方便开...【详细内容】
2021-12-07  网易Leo    Tags:Android开发   点击:(22)  评论:(0)  加入收藏
作者:fundroid这篇文章偏阅读一些,大家可以了解下 Android 的一些最新动向。每年9/10月份 Google 都会举行约为期2天的 Android Dev Summit,在活动上 Google 的技术专家们会分...【详细内容】
2021-11-30  像程序那样思考    Tags:Android开发   点击:(15)  评论:(0)  加入收藏
一、 准备工作1、安装JDK,下载地址(可能需要一个oracle账号,大家百度一下或者自行注册一个就行。尽可能选择8或者11,这两个是长期版本)Java SE | Oracle Technology Network | Or...【详细内容】
2021-11-23  永沧    Tags:Android   点击:(28)  评论:(0)  加入收藏
使用Maven Publish Plugin插件。(官方支持)一、在Library的build.gradle中配置plugins { id 'com.android.library' id 'kotlin-android' id 'k...【详细内容】
2021-11-05  羊城小阳    Tags:Android   点击:(37)  评论:(0)  加入收藏
谷歌离推出Play Store应用程序的新数据隐私部分又近了一步。应用程序开发人员现在可以通过谷歌在Play控制台的新 "数据安全表 "填写相关细节。该公司表示,所需信息将从2022年...【详细内容】
2021-10-20    中关村在线  Tags:安卓   点击:(58)  评论:(0)  加入收藏
架构究竟是什么?如何更好的理解架构?我们知道一个APP通常是由class组成,而这些class之间如何组合,相互之间又如何产生作用,就是影响这个APP的关键点。细分的话我们可以将其分为类...【详细内容】
2021-09-17  像程序那样思考    Tags:Android架构   点击:(52)  评论:(0)  加入收藏
概述当Android应用程序需要访问设备上的敏感资源时,应用程序开发人员会使用权限模型。虽然该模型使用起来非常简单,但开发人员在使用权限时容易出错,从而导致安全漏洞。本文中,...【详细内容】
2021-09-07  SecTr安全团队    Tags:Android开发   点击:(66)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条