android 数据存储

一、保存到SharedPreference

SharedPreferences 对象指向一个保存key-value pairs的文件,并为读写他们提供了简单的方法。每个 SharedPreferences 文件均由framework管理,其既可以是私有的,也可以是共享的。

获取SharedPreference

getSharedPreferences()— 如果需要多个通过名称参数来区分的shared preference文件, 名称可以通过第一个参数来指定。可在app中通过任何一个Context执行该方法。

getPreferences()— 当activity仅需要一个shared preference文件时。因为该方法会检索activity下默认的shared preference文件,并不需要提供文件名称。(它以private模式访问,该文件仅能被我们的app访问)

Caution:如果创建了一个MODE_WORLD_READABLE或者MODE_WORLD_WRITEABLE模式的shared preference文件,则其他任何app均可通过文件名访问该文件。

写Shared Preference

为了写shared preferences文件,需要通过执行edit()创建一个SharedPreferences.Editor。通过类似putInt()putString()等方法传递keys与values,接着通过commit()提交改变。

读Shared Preference

二、保存到文件

存储在内部还是外部

所有的Android设备均有两个文件存储区域:"internal" 与 "external" 。 这两个名称来自于早先的Android系统,当时大多设备都内置了不可变的内存(internal storage)及一个类似于SD card(external storage)这样的可卸载的存储部件。之后有一些设备将"internal" 与 "external" 都做成了不可卸载的内置存储,虽然如此,但是这一整块还是从逻辑上有被划分为"internal"与"external"的。只是现在不再以是否可卸载进行区分了。 下面列出了两者的区别:

Internal storage:

总是可用的

这里的文件默认只能被我们的app所访问。

当用户卸载app的时候,系统会把internal内该app相关的文件都清除干净。

Internal是我们在想确保不被用户与其他app所访问的最佳存储区域。

External storage:

并不总是可用的,因为用户有时会通过USB存储模式挂载外部存储器,当取下挂载的这部分后,就无法对其进行访问了。

是大家都可以访问的,因此保存在这里的文件可能被其他程序访问。

当用户卸载我们的app时,系统仅仅会删除external根目录(getExternalFilesDir())下的相关文件。

External是在不需要严格的访问权限并且希望这些文件能够被其他app所共享或者是允许用户通过电脑访问时的最佳存储区域。

Tip:尽管app是默认被安装到internal storage的,我们还是可以通过在程序的manifest文件中声明android:installLocation属性来指定程序安装到external storage。当某个程序的安装文件很大且用户的external storage空间大于internal storage时,用户会倾向于将该程序安装到external storage。更多安装信息见App Install Location

获取External存储的权限

为了写数据到external storage, 必须在你manifest文件中请求WRITE_EXTERNAL_STORAGE权限:

Caution:目前,所有的apps都可以在不指定某个专门的权限下做external storage的动作。但这在以后的安卓版本中会有所改变。如果我们的app只需要的权限(不是写), 那么将需要声明READ_EXTERNAL_STORAGE权限。为了确保app能持续地正常工作,我们现在在编写程序时就需要声明读权限。

但是,如果我们的程序有声明WRITE_EXTERNAL_STORAGE权限,那么就默认有了的权限。

保存到Internal Storage

当保存文件到internal storage时,可以通过执行下面两个方法之一来获取合适的目录作为FILE的对象:

getFilesDir(): 返回一个File,代表了我们app的internal目录。

getCacheDir(): 返回一个File,代表了我们app的internal缓存目录。请确保这个目录下的文件能够在一旦不再需要的时候马上被删除,并对其大小进行合理限制,例如1MB 。系统的内部存储空间不够时,会自行选择删除缓存文件。

可以使用File()构造器在那些目录下创建一个新的文件,如下:

File file = new File(context.getFilesDir(), filename);

同样,也可以执行openFileOutput()获取一个FileOutputStream用于写文件到internal目录。如下:

同样,也可以执行openFileOutput()获取一个FileOutputStream用于写文件到internal目录。如下:

如果需要缓存一些文件,可以使用createTempFile()。例如:下面的方法从URL中抽取了一个文件名,然后再在程序的internal缓存目录下创建了一个以这个文件名命名的文件。

Note:我们的app的internal storage 目录以app的包名作为标识存放在Android文件系统的特定目录下[data/data/com.example.xx]。 从技术上讲,如果文件被设置为可读的,那么其他app就可以读取该internal文件。然而,其他app需要知道包名与文件名。若没有设置为可读或者可写,其他app是没有办法读写的。因此我们只要使用了MODE_PRIVATE,那么这些文件就不可能被其他app所访问。

保存文件到External Storage

因为external storage可能是不可用的,比如遇到SD卡被拔出等情况时。因此在访问之前应对其可用性进行检查。我们可以通过执行getExternalStorageState()来查询external storage的状态。若返回状态为MEDIA_MOUNTED, 则可以读写。示例如下:

尽管external storage对于用户与其他app是可修改的,我们可能会保存下面两种类型的文件。

Public files:这些文件对与用户与其他app来说是public的,当用户卸载我们的app时,这些文件应该保留。例如,那些被我们的app拍摄的图片或者下载的文件。

Private files: 这些文件完全被我们的app所私有,它们应该在app被卸载时删除。尽管由于存储在external storage,那些文件从技术上而言可以被用户与其他app所访问,但实际上那些文件对于其他app没有任何意义。因此,当用户卸载我们的app时,系统会删除其下的private目录。例如,那些被我们的app下载的缓存文件。

想要将文件以public形式保存在external storage中,请使用getExternalStoragePublicDirectory()方法来获取一个 File 对象,该对象表示存储在external storage的目录。这个方法会需要带有一个特定的参数来指定这些public的文件类型,以便于与其他public文件进行分类。参数类型包括DIRECTORY_MUSIC或者DIRECTORY_PICTURES. 如下:

如果刚开始的时候,没有预定义的子目录存放我们的文件,可以在 getExternalFilesDir()方法中传递null. 它会返回app在external storage下的private的根目录。

请记住,getExternalFilesDir() 方法会创建的目录会在app被卸载时被系统删除。如果我们的文件想在app被删除时仍然保留,请使用getExternalStoragePublicDirectory().

无论是使用 getExternalStoragePublicDirectory() 来存储可以共享的文件,还是使用 getExternalFilesDir() 来储存那些对于我们的app来说是私有的文件,有一点很重要,那就是要使用那些类似DIRECTORY_PICTURES的API的常量。那些目录类型参数可以确保那些文件被系统正确的对待。例如,那些以DIRECTORY_RINGTONES类型保存的文件就会被系统的media scanner认为是ringtone而不是音乐。

查询剩余空间

如果事先知道想要保存的文件大小,可以通过执行getFreeSpace()orgetTotalSpace()来判断是否有足够的空间来保存文件,从而避免发生IOException。那些方法提供了当前可用的空间还有存储系统的总容量。

然而,系统并不能保证可以写入通过getFreeSpace()查询到的容量文件, 如果查询的剩余容量比我们的文件大小多几MB,或者说文件系统使用率还不足90%,这样则可以继续进行写的操作,否则最好不要写进去。

Note:并没有强制要求在写文件之前去检查剩余容量。我们可以尝试先做写的动作,然后通过捕获 IOException 。这种做法仅适合于事先并不知道想要写的文件的确切大小。例如,如果在把PNG图片转换成JPEG之前,我们并不知道最终生成的图片大小是多少。

删除文件

在不需要使用某些文件的时候应删除它。删除文件最直接的方法是直接执行文件的delete()方法。

myFile.delete();

如果文件是保存在internal storage,我们可以通过Context来访问并通过执行deleteFile()进行删除

myContext.deleteFile(fileName);

Note:当用户卸载我们的app时,android系统会删除以下文件:

所有保存到internal storage的文件。

所有使用getExternalFilesDir()方式保存在external storage的文件。

然而,通常来说,我们应该手动删除所有通过 getCacheDir() 方式创建的缓存文件,以及那些不会再用到的文件。

三、保存到数据库

这里就不写,可以使用第三方的数据库比较方便,比如greendao,realm等等

源地址:http://wiki.jikexueyuan.com/project/android-training-geek/data-storage-index.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容