您的位置:首页 > 移动开发 > Android开发

理解 Android 本地数据存储 API

2011-06-13 21:58 591 查看

理解 Android 本地数据存储 API

利用首选项、SQLite 和内部及外部内存 API

C. Enrique Ortiz
, 开发人员兼作家, About Mobility Weblog
C. Enrique Ortiz
是一位经验丰富的移动技术专家、开发人员和作家。他在 About Mobility
上撰写博客,他是 Austin chapter of MobileMonday 的创始人。
简介:
对于需要跨应用程序执行期间或生命期而维护重要信息的应用程序来说,能够在移动设备上本地存储数据
是一种非常关键的功能。作为一名开发人员,您经常需要存储诸如用户首选项或应用程序配置之类的信息。您还必须根据一些特征(比如访问可见性)决定是否需要
涉及内部或外部存储器,或者是否需要处理更复杂的、结构化的数据类型。跟随本文学习 Android 数据存储
API,具体来讲就是首选项、SQLite 和内部及外部内存 API。

本文的标签:
api
, web_服务
, xml
, 应用开发
, 集成架构

标记本文!

发布日期:
2010 年 12 月 27 日

级别:
中级

原创语言:
英文

访问情况
9381 次浏览

建议:
0 (添加评论
)











平均分 (共 15 个评分 )

常用缩写词

ADT:Android 开发工具

API:应用程序编程接口

IDE:集成开发环境

JDK:Java 开发工具包

JSON:JavaScript 对象表示法

SDK:软件开发工具包

SQL:结构化查询语言

UI:用户界面

XML:可扩展标记语言

前提条件

要跟随本文,需要具备以下技能和工具:

基本了解 Java™ 技术和如何使用 Eclipse(或者您喜欢的 IDE)

Java Development Kit(需要版本 5 或 6)

Eclipse(版本 3.4 或 3.5)

Android SDK 和 ADT 插件

关于下载和设置信息,请参见本文末尾的 参考资料


回页首

样例应用程序

为了突出 Android 应用程序开发的本地存储方面,我这里介绍一个样例应用程序,它允许您测试各种类型 API 的执行。有 源代码
可供下载。该应用程序支持 图 1
中的操作。

图 1. 用例



图 1
列出了以下用例:

管理和存储首选项

从应用程序资产加载信息

将信息导出到内部内存、外部内存和本地数据库

从内部内存和本地数据库读取数据

清除已存储的信息

在屏幕上查看信息

通篇文章中,详细介绍了在应用程序中使用本地存储,如下:

从用户捕获首选项,本地存储起来,并在整个应用程序中加以使用。

从内部应用程序资产检索一个用户图片,存储在本地内部内存和外部内存中,并呈现在屏幕上。

从应用程序的资产检索一个 JSON 格式的好友列表。解析并存储在本地内部内存、外部内存和关系数据库中,再呈现在屏幕上。

样例应用程序定义了 表 1
中的类。

表 1. 样例应用程序中的类

说明
MainActivity

Main Activity;大多数样例代码都驻留在这里
Friend

描绘一个 Friend
AppPreferenceActivity

Preferences Activity 和屏幕
DBHelper

一个用于 SQLite 数据库管理的帮助器类
示例应用程序使用了两种类型的数据。第一种是应用程序首选项,存储为名-值对。对于首选项,定义了以下信息:

一个 filename
,用于加载和存储好友姓名列表

一个 filename
,用于加载和存储用户的一幅图片

一个 flag
,如果设置了,那么表示在应用程序启动时自动删除所有已存储的数据

第二种类型的数据是好友列表。好友列表最初表示为 Facebook Graph API JSON 格式,包含一组姓名和好友对象(参见 清单 1
)。

清单 1. 好友列表(Facebook Graph API JSON 格式)

{

"data": [

{

"name": "Edmund Troche",

"id": "500067699"

}

]

}

上面的简单格式使得
Friend

对象和数据库模式也简单。清单 2
展示了
Friend

类。

清单 2.
Friend



package com.cenriqueortiz.tutorials.datastore;

import android.graphics.Bitmap;

/**

* Represents a Friend

*/

public class Friend {

public String id;

public String name;

public byte[] picture;

public Bitmap pictureBitmap;;

}

除了 ID 和姓名之外,样例应用程序也保留了对好友图片的引用。尽管样例应用程序没有使用这些引用,但是您很容易扩展样例应用程序,以从 Facebook 检索图片并显示在主屏幕中。

数据库模式包含单个表,用于存储 Friend 的信息。表有三列:

惟一的 ID 或键

Facebook ID

Friend 的姓名

清单 3
展示了相应关系表声明的 SQL 语句。

清单 3. Friend 数据库表

db.execSQL("create table " + TABLE_NAME + " (_id integer primary key autoincrement, "

+ " fid text not null, name text not null) ");

根据此信息,您可以在主屏幕上显示姓名;使用 ID,您可以检索所选用户的额外详细信息。在样例应用程序中,只显示了姓名。检索额外信息留给您去试验。注意,您很容易更改代码,以直接转向 Facebook。

回页首

存储应用程序首选项

本节介绍 Preferences API 和屏幕。Android API 提供很多方式处理首选项。其中一种方式是直接使用
SharedPreferences

,并使用您自己的屏幕设计和首选项管理。第二种方法是使用
PreferenceActivity

PreferenceActivity

自动负责首选项如何呈现在屏幕上(默认情况下,看起来跟系统首选项一样),并通过使用
SharedPreferences

在用户与每个首选项交互时自动存储或保存首选项。

为了简化样例应用程序,使用一个
PreferenceActivity

来管理首选项和首选项屏幕(参见 图 2
)。首选项屏幕显示两个部分:Assets 和 Auto Settings。在 Assets 下,您可以为 Friends List 和 Picture 选项输入文件名。在 Auto Settings 下,您可以选中一个复选框,以便在启动时删除信息。

图 2. 实现的 Preferences 屏幕



图 2
中,布局是用 XML 以声明式方法定义的(不是以编程方式);声明式 XML 是首选方法,因为它保持了源代码的清晰可读。清单 4
展示了 Preferences UI 的 XML 声明。

清单 4. Preferences 屏幕的 XML 声明

<?xml version="1.0" encoding="utf-8"?>

<PreferenceScreen

xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/prefs_screen"

android:key="preferencescreen"

>

<PreferenceCategory android:title="Assets">

<EditTextPreference

android:key="@string/prefs_assetname_friendslist_key"

android:title="Friends List"

android:summary="Please enter filename"

android:defaultValue="friends.txt"

/>

<EditTextPreference

android:key="@string/prefs_assetname_picture_key"

android:title="Picture"

android:summary="Please enter filename"

android:defaultValue="pict2.jpg"

/>

</PreferenceCategory>

<PreferenceCategory android:title="Auto Settings">

<CheckBoxPreference

android:key="@string/prefs_autodelete_key"

android:title="Delete at Startup"

android:summary="Check to clear at startup"

android:defaultValue="false"

/>

</PreferenceCategory>

</PreferenceScreen>

PreferenceScreen

包含
EditTextPreference

的两个实例、一个
CheckBoxPreference

和两个由
PreferenceCategory

定义的类别组(一个用于
Asset

,另一个用于
Auto Settings

)。

在样例应用程序中,设计要求 Preference 屏幕使用菜单项进行调用。为此,使用一条 Intent 消息来调用叫做
AppPreferenceActivity

的 Preference Screen Activity(参见 清单 5
)。注意,我没有详细介绍 Intent 如何工作。关于 Intent 的更多信息,请参见 参考资料


清单 5.
AppPreferenceActivity



/*

* AppPreferenceActivity is a basic PreferenceActivity

* C. Enrique Ortiz | http://CEnriqueOrtiz.com 
*/

package com.cenriqueortiz.tutorials.datastore;

import android.os.Bundle;

import android.preference.PreferenceActivity;

public class AppPreferenceActivity extends PreferenceActivity {

/**

* Default Constructor

*/

public AppPreferenceActivity() {}

/**

* Called when the activity is first created.

*   Inflate the Preferences Screen XML declaration.

*/

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

addPreferencesFromResource(R.xml.prefs); // Inflate the XML declaration

}

}

在样例应用程序中,像 清单 6
中一样,从菜单项处理程序中调用 Intent。

清单 6. 使用 Intent 调用 Preference Activity

/**

* Invoked when a menu item has been selected

*/

@Override

public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

// Case: Bring up the Preferences Screen

case R.id.menu_prefs: // Preferences

// Launch the Preference Activity

Intent i = new Intent(this, AppPreferenceActivity.class);

startActivity(i);

break;

case R.id.menu...:

:

break;

}

return true;

}

此外,您必须在 AndroidManifest XML 文件中定义所有的 Intent,如 清单 7
所示。

清单 7. 在 AndroidManifest.xml 中定义 Intent

:

<application android:icon="@drawable/icon" android:label="@string/app_name">

:

:

<activity

android:name="AppPreferenceActivity"

android:label="Preferences">

</activity>

:

</application>

回想一下,
PreferenceActivity

使用
SharedPreferences

在用户与首选项屏幕交互时自动存储首选项。然后应用程序在执行各种任务时使用这些首选项。清单 8
展示了如何直接使用
SharedPreferences

来加载存储的首选项;关于加载的首选项在整个样例代码中是如何被使用的,您可以参考相应的样例代码。此外,清单 8
也展示了如何利用
SharedPreferences

直接存储首选项,以防您喜欢自己管理首选项(不是通过
PrefenceActivity

),使用了一个
Editor



清单 8
展示了如何使用
SharedPreferences

加载已存储的首选项,以及如何使用
Editor

更改已存储的首选项。

清单 8. 使用
SharedPreferences



/////////////////////////////////////////////////////////////

// The following methods show how to use the SharedPreferences

/////////////////////////////////////////////////////////////

/**

* Retrieves the Auto delete preference

* @return the value of auto delete

*/

public boolean prefsGetAutoDelete() {

boolean v = false;

SharedPreferences sprefs =

PreferenceManager.getDefaultSharedPreferences(appContext);

String key = appContext.getString(R.string.prefs_autodelete_key);

try {

v = sprefs.getBoolean(key, false);

} catch (ClassCastException e) {

}

return v;

}

/**

* Sets the auto delete preference

* @param v the value to set

*/

public void  prefsSetAutoDelete(boolean v) {

SharedPreferences sprefs =

PreferenceManager.getDefaultSharedPreferences(appContext);

Editor e = sprefs.edit();

String key = appContext.getString(R.string.prefs_autodelete_key);

e.putBoolean(key, v);

e.commit();

}

接下来,将介绍如何使用数据库来存储数据。

回页首

使用 SQLite 数据库

Android 通过 SQLite 提供对本地关系数据库的支持。表中(定义在以下代码清单中)汇总了样例应用程序中使用的重要数据库类。

样例应用程序使用了一个
DBHelper

类来封装一些数据库操作(参见 清单 9
)。

清单 9.
DBHelper



package com.cenriqueortiz.tutorials.datastore;

import java.util.ArrayList;

import android.content.Context;

import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteOpenHelper;

public class DBHelper extends SQLiteOpenHelper {

为数据库版本、数据库名称和表名称定义了很多常量(参见 清单 10
)。

清单 10. 初始化
DBHelper



private SQLiteDatabase db;

private static final int DATABASE_VERSION = 1;

private static final String DB_NAME = "sample.db";

private static final String TABLE_NAME = "friends";

/**

* Constructor

* @param context the application context

*/

public DBHelper(Context context) {

super(context, DB_NAME, null, DATABASE_VERSION);

db = getWritableDatabase();

}

在准备好创建数据库时,会调用
onCreate()

方法。在该方法中,创建表(参见 清单 11
)。

清单 11. 创建数据库表

/**

* Called at the time to create the DB.

* The create DB statement

* @param the SQLite DB

*/

@Override

public void onCreate(SQLiteDatabase db) {

db.execSQL(

"create table " + TABLE_NAME + " (_id integer primary key autoincrement,

" + " fid text not null, name text not null) ");

}

insert()

方法在信息导出到数据库时由
MainActivity

调用(参见 清单 12
)。

清单 12. 插入一行

/**

* The Insert DB statement

* @param id the friends id to insert

* @param name the friend's name to insert

*/

public void insert(String id, String name) {

db.execSQL("INSERT INTO friends('fid', 'name') values ('"

+ id + "', '"

+ name + "')");

}

deleteAll()

方法在清理数据库时由
MainActivity

调用。它删除表(参见 清单 13
)。

清单 13. 删除数据库表

/**

* Wipe out the DB

*/

public void clearAll() {

db.delete(TABLE_NAME, null, null);

}

提供了两个
SELECT ALL

方法:
cursorSelectAll()

listSelectAll()

,前者返回一个游标,后者返回一个
Friend

对象
ArrayList

。这些方法在从数据库加载信息时由
MainActivity

调用(参见 清单 14
)。

清单 14. 运行返回
ArrayList

Select All



/**

* Select All returns a cursor

* @return the cursor for the DB selection

*/

public Cursor cursorSelectAll() {

Cursor cursor = this.db.query(

TABLE_NAME, // Table Name

new String[] { "fid", "name" }, // Columns to return

null,       // SQL WHERE

null,       // Selection Args

null,       // SQL GROUP BY

null,       // SQL HAVING

"name");    // SQL ORDER BY

return cursor;

}

listSelectAll()

方法返回
ArrayList

容器中选定的行,该容器由
MainActivity

用来将它绑定到
MainScreen ListView

(参见 清单 15
)。

清单 15. 运行返回游标的
Select All



/**

* Select All that returns an ArrayList

* @return the ArrayList for the DB selection

*/

public ArrayList<Friend> listSelectAll() {

ArrayList<Friend> list = new ArrayList<Friend>();

Cursor cursor = this.db.query(TABLE_NAME, new String[] { "fid", "name" },

null, null, null, null, "name");

if (cursor.moveToFirst()) {

do {

Friend f = new Friend();

f.id = cursor.getString(0);

f.name = cursor.getString(1);

list.add(f);

} while (cursor.moveToNext());

}

if (cursor != null && !cursor.isClosed()) {

cursor.close();

}

return list;

}

如果检测到数据库版本更改,就会调用
onUpgrade()

方法(参见 清单 16
)。

清单 16. 检测数据库版本是否更改

/**

* Invoked if a DB upgrade (version change) has been detected

*/

@Override

/**

* Invoked if a DB upgrade (version change) has been detected

*/

@Override

public void onUpgrade(SQLiteDatabase db,

int oldVersion, int newVersion) {

// Here add any steps needed due to version upgrade

// for example, data format conversions, old tables

// no longer needed, etc

}

}

整个
MainActivity

中,当您将信息导出到数据库、从数据库加载信息以及清理数据库时,都会使用
DBHelper

。第一件事是在创建
MainActivity

时实例化
DBHelper

。在
onCreate()

时执行的其他任务包括初始化不同的屏幕视图(参见 清单 17
)。

清单 17.
MainActivity onCreate()

初始化数据库


public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

appContext = this;

setContentView(R.layout.main);

dbHelper = new DBHelper(this);

listView = (ListView) findViewById(R.id.friendsview);

friendsArrayAdapter = new FriendsArrayAdapter(

this, R.layout.rowlayout, friends);

listView.setAdapter(friendsArrayAdapter);

:

:

}

清单 18
展示了如何从资产加载好友列表以及如何将之解析并插入数据库中。

清单 18.
MainActivity

插入到数据库中


String fname = prefsGetFilename();

if (fname != null && fname.length() > 0) {

buffer = getAsset(fname);

// Parse the JSON file

String friendslist = new String(buffer);

final JSONObject json = new JSONObject(friendslist);

JSONArray d = json.getJSONArray("data");

int l = d.length();

for (int i2=0; i2<l; i2++) {

JSONObject o = d.getJSONObject(i2);

String n = o.getString("name");

String id = o.getString("id");

dbHelper.insert(id, n);

}

// Only the original owner thread can touch its views

MainActivity.this.runOnUiThread(new Runnable() {

public void run() {

friendsArrayAdapter.notifyDataSetChanged();

}

});

}

清单 19
展示了如何执行
SELECT
ALL

以及如何将数据绑定到主屏幕
ListView



清单 19.
MainActivity

Select All

和将数据绑定到
ListView



final ArrayList<Friend> dbFriends = dbHelper.listSelectAll();

if (dbFriends != null) {

// Only the original owner thread can touch its views

MainActivity.this.runOnUiThread(new Runnable() {

public void run() {

friendsArrayAdapter =

new FriendsArrayAdapter(

MainActivity.this, R.layout.rowlayout, dbFriends);

listView.setAdapter(friendsArrayAdapter);

friendsArrayAdapter.notifyDataSetChanged();

}

});

}

接下来,了解一下在示例应用程序中使用 Internal Storage API。

回页首

为私有数据使用设备的内部存储器

有了数据存储 API,您可以使用内部存储器存储数据。信息可以是私有的,您可以有选择地让其他应用程序对之具有读或写的访问权限。本节介绍这个存储私有数据的 API,它使用
android.content.Context.openFileInput

openFileOutput

getCacheDir()

来高速缓存数据,而不是永久地存储。

清单 20
中的代码片段展示了如何从内部私有存储器读取数据。使得存储器为私有的方法是对
openFileOutput()

使用
MODE_PRIVATE



清单 20. 从本地私有存储器读取数据

/**

* Writes content to internal storage making the content private to

* the application. The method can be easily changed to take the MODE

* as argument and let the caller dictate the visibility:

* MODE_PRIVATE, MODE_WORLD_WRITEABLE, MODE_WORLD_READABLE, etc.

*

* @param filename - the name of the file to create

* @param content - the content to write

*/

public void writeInternalStoragePrivate(

String filename, byte[] content) {

try {

//MODE_PRIVATE creates/replaces a file and makes

//  it private to your application. Other modes:

//    MODE_WORLD_WRITEABLE

//    MODE_WORLD_READABLE

//    MODE_APPEND

FileOutputStream fos =

openFileOutput(filename, Context.MODE_PRIVATE);

fos.write(content);

fos.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

清单 21
中的代码片段展示了如何从内部私有存储器读取数据;注意
openFileInput()

的使用。

清单 21. 从内部私有存储器读取数据

/**

* Reads a file from internal storage

* @param filename the file to read from

* @return the file content

*/

public byte[] readInternalStoragePrivate(String filename) {

int len = 1024;

byte[] buffer = new byte[len];

try {

FileInputStream fis = openFileInput(filename);

ByteArrayOutputStream baos = new ByteArrayOutputStream();

int nrb = fis.read(buffer, 0, len); // read up to len bytes

while (nrb != -1) {

baos.write(buffer, 0, nrb);

nrb = fis.read(buffer, 0, len);

}

buffer = baos.toByteArray();

fis.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return buffer;

}

清单 22
展示了如何从内部私有存储器删除数据。

清单 22. 从本地私有存储器删除数据

/**

* Delete internal private file

* @param filename - the filename to delete

*/

public void deleteInternalStoragePrivate(String filename) {

File file = getFileStreamPath(filename);

if (file != null) {

file.delete();

}

}

现在可以来看为公共数据使用外部存储器了。

回页首

为公共数据使用设备的外部存储器

有了数据存储 API,您可以使用外部存储器存储数据。信息可以是私有的,您可以有选择地让其他应用程序对之具有读或写的访问权限。本节您将对此 API 进行编程,以便使用包括
getExternalStorageState()

getExternalFilesDir()

getExternalStorageDirectory()

getExternalStoragePublicDirectory()

在内的很多 API 来存储公共数据。您为公共数据使用下面的路径:
/Android/data/<package_name>/files/



在使用外部存储器之前,必须看看它是否可用,是否可写。下面两个代码片段展示了测试这些条件的帮助器方法。清单 23
测试外部存储器是否可用。

清单 23. 测试外部存储器是否可用

/**

* Helper Method to Test if external Storage is Available

*/

public boolean isExternalStorageAvailable() {

boolean state = false;

String extStorageState = Environment.getExternalStorageState();

if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {

state = true;

}

return state;

}

清单 24
测试外部存储器是否只可读。

清单 24. 测试外部存储器是否只可读

/**

* Helper Method to Test if external Storage is read only

*/

public boolean isExternalStorageReadOnly() {

boolean state = false;

String extStorageState = Environment.getExternalStorageState();

if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {

state = true;

}

return state;

}

清单 25
展示了如何写到外部存储器,以存储公共数据。

清单 25. 写到外部内存

/**

* Write to external public directory

* @param filename - the filename to write to

* @param content - the content to write

*/

public void writeToExternalStoragePublic(String filename, byte[] content) {

// API Level 7 or lower, use getExternalStorageDirectory()

//  to open a File that represents the root of the external

// storage, but writing to root is not recommended, and instead

// application should write to application-specific directory, as shown below.

String packageName = this.getPackageName();

String path = "/Android/data/" + packageName + "/files/";

if (isExternalStorageAvailable() &&

!isExternalStorageReadOnly()) {

try {

File file = new File(path, filename);

file.mkdirs();

FileOutputStream fos = new FileOutputStream(file);

fos.write(content);

fos.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

}

清单 26
展示了如何从外部存储器读取数据。

清单 26. 从外部内存读取数据

/**

* Reads a file from internal storage

* @param filename - the filename to read from

* @return the file contents

*/

public byte[] readExternallStoragePublic(String filename) {

int len = 1024;

byte[] buffer = new byte[len];

String packageName = this.getPackageName();

String path = "/Android/data/" + packageName + "/files/";

if (!isExternalStorageReadOnly()) {

try {

File file = new File(path, filename);

FileInputStream fis = new FileInputStream(file);

ByteArrayOutputStream baos = new ByteArrayOutputStream();

int nrb = fis.read(buffer, 0, len); //read up to len bytes

while (nrb != -1) {

baos.write(buffer, 0, nrb);

nrb = fis.read(buffer, 0, len);

}

buffer = baos.toByteArray();

fis.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

return buffer;

}

清单 27
中的代码片段展示了如何从外部内存删除文件。

清单 27. 从外部内存删除文件

/**

* Delete external public file

* @param filename - the filename to write to

*/

void deleteExternalStoragePublicFile(String filename) {

String packageName = this.getPackageName();

String path = "/Android/data/" + packageName + "/files/"+filename;

File file = new File(path, filename);

if (file != null) {

file.delete();

}

}

处理外部存储器需要特殊的权限
WRITE_EXTERNAL_STORAGE

,它通过 AndroidManifest.xml 请求得到(参见 清单 28
)。

清单 28.
WRITE_EXTERNAL_STORAGE



<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

外部存储 API 通过根据文件类型(比如 Pictures、Ringtones)将文件存储在预先确定的目录中,允许您公共地存储文件。本文没有介绍这种方法,但是您应该熟悉它。此外,记住外部存储器中的文件任何时候都可能消失。

回页首

相关的方法

如果您具有不需要长期永久保存的临时文件,那么可以将这些文件存储在高速缓存中。高速缓存是一种特殊的内存,可以用于存储中小型数据(少于兆字节),但是您一定要知道,取决于有多少内存可用,高速缓存的内容任何时候都可能被清除。

清单 29
展示了一个帮助器方法,它返回到内部内存中高速缓存的路径。

清单 29. 检索到内部内存高速缓存的路径

/**

* Helper method to retrieve the absolute path to the application

* specific internal cache directory on the file system. These files

* will be ones that get deleted when the application is uninstalled or when

* the device runs low on storage. There is no guarantee when these

* files will be deleted.

*

* Note: This uses a Level 8+ API.

*

* @return the absolute path to the application specific cache

* directory

*/

public String getInternalCacheDirectory() {

String cacheDirPath = null;

File cacheDir = getCacheDir();

if (cacheDir != null) {

cacheDirPath = cacheDir.getPath();

}

return cacheDirPath;

}

清单 30
展示了一个帮助器方法,它返回到外部内存中高速缓存的路径。

清单 30. 检索到外部内存高速缓存的路径

/**

* Helper method to retrieve the absolute path to the application

* specific external cache directory on the file system. These files

* will be ones that get deleted when the application is uninstalled or when

* the device runs low on storage. There is no guarantee when these

* files will be deleted.

*

* Note: This uses a Level 8+ API.

*

* @return the absolute path to the application specific cache

* directory

*/

public String getExternalCacheDirectory() {

String extCacheDirPath = null;

File cacheDir = getExternalCacheDir();

if (cacheDir != null) {

extCacheDirPath = cacheDir.getPath();

}

return extCacheDirPath;

}

通过使用示例应用程序,您现在应该很好地理解了如何为公共数据使用设备的外部存储器。

回页首

结束语

本文介绍了几个 Android 存储 API,从首选项到使用 SQLite 和内部及外部内存。利用首选项
API,您可以让自己的应用程序收集和存储简单的首选项信息。使用 SQLite
API,您可以存储更复杂的数据,利用内部和外部存储器,您可以存储对应用程序是私有的或者对其他应用程序公共可用的文件。跨多个会话持久存储的已存储数
据让您的应用程序甚至在与网络断开连接时仍然能够工作。您现在应该掌握了在开发 Android 应用程序时利用所有这些类型的存储器。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: