Android为你供给了若干选项用于存储运用程序数据。挑选何种计划时状况而定。比方,数据仅为你的运用所运用,或是可是为其他运用(以及用户)所同享。又比方,你的数据需求多少空间。
数据存储有以下几个挑选:
Data_Storage#.E4.BD.BF.E7.94.A8.E5.85.B1.E4.BA.AB.E7.9A.84.E9.85.8D.E7.BD.AE_-_Using_Shared_Preferences|Shared Preferences|公共装备-Shared Preferences
经过键值对的办法存储私有的原始数据。
Data_Storage#.E4.BD.BF.E7.94.A8.E5.86.85.E9.83.A8.E5.AD.98.E5.82.A8_-_Using_the_Internal_Storage|Internal Storage|内部存储-Internal Storage
在存储器上存储私有的数据。
Data_Storage#.E4.BD.BF.E7.94.A8.E5.86.85.E9.83.A8.E5.AD.98.E5.82.A8_-_Using_the_Internal_Storage|External Storage | 外部存储 – External Storage
在外部存储器上存储揭露的数据。
Data_Storage#.E4.BD.BF.E7.94.A8.E6.95.B0.E6.8D.AE.E5.BA.93_-_Using_Databases|SQLite Database | SQLite数据库 – SQLite Database
在私有的数据库中存储结构化的数据。
Data_Storage#.E4.BD.BF.E7.94.A8.E7.BD.91.E7.BB.9C.E8.BF.9E.E6.8E.A5_-_Using_a_Network_Connection|Network Connection | 网络连接 – Network Connection
运用你的网络服务器存储数据。
Android供给了露出私有数据给其他运用的办法——运用一个内容供给器(content provider)。内容供给器是一个可选的组件,为你的运用程序数据供给读/写权限,并受制于你给定的约束。关于运用内容供给器的更多细节,请检查Content Providers的文档。
运用同享的装备 – Using Shared Preferences
SharedPreferences类供给了一个通用的结构,用于保存和检索以耐久化的键值对方式存储的原始数据类型。你能够运用SharedPreferences保存恣意类型的原始数据:布尔(boolean),浮点,(float),整型(int),长整型(long)和字符串(string)。这些数据将会存放在用户会话中(即便你的运用程序现已退出)。
* 用户装备*
同享的装备并非一定要保存用户装备,例如用户挑选和哪个铃声。假如你有爱好为你的运用创立用户装备,请参阅PreferenceActivity。它供给了一个Activity的结构,能够用来创立耐久化的用户装备(运用同享的装备)。
在运用程序中获得SharedPreferences目标,运用以下两种办法之一:
* int) getSharedPreferences() getPreferences()](http://developer.android.com/reference/android/content/Context.html#getSharedPreferencesjava.lang.String,)( – 当你仅需求一个装备文件。因为这是你的Activity的仅有一个装备文件,所以不用供给称号。
向SharedPreferences写入值的过程:
1、调用edit(),获得一个SharedPreferences.Editor。
2、运用形如boolean) putBoolean() putString()](http://developer.android.com/reference/android/content/SharedPreferences.Editor.html#putStringjava.lang.String,)这样的办法添加值。(
3、运用commit()提交新值。
从SharedPreferences读取值,运用它的办法,例如boolean) getBoolean() getString()](http://developer.android.com/reference/android/content/SharedPreferences.html#getStringjava.lang.String,)即可。(
这是一个比方,在一个核算器中运用无声的按键保存一个装备:
class extends { static String PREFS_NAME ; protected (){ .onCreate); . // Restore preferences color:#660>(PREFS_NAME0boolean silent settings(, ); setSilent); @Override void onStopsuper(); // All objects are from android.context.Context color:#660>(PREFS_NAME0SharedPreferencesEditor editor settings(); editor(, mSilentMode// Commit the edits! editor(); }
运用内部存储 – Using the Internal Storage
你能够直接将文件保存在设备上的内部存储中。缺省状况下,存放于内部存储的文件为你的运用程序所私有,其他运用程序不行以拜访它们(其他用户亦然)。当用户卸载你的运用,这些文件也被删去。
在内部存储中创立并写入一个私有文件:
1、调用openFileOutput(),传入文件名和操作形式。办法回来一个FileOutputStream目标。
2、运用write()写文件。
3、运用close()封闭文件流。
例如:
color:#080>hello_fileString color:#080>hello world!FileOutputStream fos openFileOutput, .MODE_PRIVATE.writestring());fos();
MODE_PRIVATE创立文件(或以同名文件替换),并为你的运用所私有。其他可用的形式有:MODE_APPEND, MODE_WORLD_READABLE, 和MODE_WORLD_WRITEABLE。
从内部存储中读一个文件:
1、调用openFileInput(),并传递需求读取的文件的称号。这个办法回来一个FileInputStream。
2、运用read()从文件中读取数据。
3、运用close()封闭文件流。
提示:假如你想在编译时往你的运用中存入一个静态文件,就得把文件保存到项目的res/raw目录下。你能够调用openRawResource()并传递资源的ID(R.raw.)来翻开它。这个办法回来一个InputStream,你能够运用它读取文件,但不行以写入这个原始文件。
保存缓存文件
假如你想要缓存一些数据,而不是保存它们,你应该调用getCacheDir()翻开一个File目标,它表明你的运用应当保存暂时缓存文件的内部目录。
其他有用的办法
getFilesDir() 获得内部文件在文件体系中保存方位的绝对路径。
getDir() 创立(或许翻开已存在的)内部存储空间地点的目录。
deleteFile() 删去内部存储的一个文件。
fileList() 回来当时由你的运用保存的文件的列表。
运用外部存储 – Using the External Storage
一切兼容Android的设备都支撑一个可同享的“外部存储(external storage)”,可用来保存文件。这能够使一个可移动的存储设备(比方SD卡)或许一个内部的(不行移动的)存储。保存在外部存储的文件是可读的。而且当用于传输数据的USB大容量存储选项启用时,用户能够在核算机上修正它们。
留意:* 假如用户挂载外部存储到核算机上,或许移除媒体,外部文件将会消失不见。而且关于这些保存在外部存储的文件,没有强制的安全措施。一切的运用都能够读/写这些文件。用户也能够删去它们。
检测媒体可用性
在你对外部存储做任何事情之前,你总是应当调用getExternalStorageState()以检测媒体是否可用。媒体或许被核算机挂载,或许丢掉,或许只读,或许处于某些其他状况。比方,这是示例代码:
color:#008>falseboolean mExternalStorageWriteable ;color:#606>Environment();(.MEDIA_MOUNTED(state{ color:#660>color:#008>true} if Environment.equals)) // We can only read the media mExternalStorageAvailable ; mExternalStorageWriteable ;else // Something else is wrong. It may be one of many other states, but all we need color:#660>color:#008>false}
这个比方检测了外部存储是否可读或可写。getExternalStorageState()办法回来你想要检测的其他状况。比方,媒体是否被同享(已连接到一台核算机),是否彻底丢掉,是否被移除等等。当你的运用需求拜访媒体时,你能够根据这些以更具体的信息告诉用户。
拜访坐落外部存储的文件
假如你正在运用API Level 8或许更高版别,运用getExternalFilesDir()翻开一个文件目标,它表明你的运用应当保存文件地点的外部存储目录。这个办法需求一个类型参数,指定你需求的子目录类型,比方DIRECTORY_MUSIC或许DIRECTORY_RINGTONES(传递null表明你的运用程序的目录地点的根目录)。如有必要,这个办法将会创立一个目录。经过指定目录的类型,你坚信Android的媒体扫描器会将体系中的文件正确分类(例如,铃声将被归类为铃声而不是音乐)。假如用户卸载了你的运用,这个目录以及它的内容将会被删去。
假如你正在运用API Level 7或许更低版别,运用getExternalStorageDirectory()翻开一个文件目标,它表明外部存储的根目录。接下来,你应当写入你的数据在一下目录:
/Android/data//files/
com.example.android.app。假如用户的设备正在运转API Level 8或许更高版别,且用户卸载了你的运用,这个目录和它的内容将会被删去。
保存应当同享的文件
在媒体扫描器下躲藏你的文件
在你的外部文件目录中放置包括一个空的文件,命名为.nomedia(留意文件名前缀的点)。这会阻挠Android的媒体扫描器读取你的媒体文件,并并在相似Gallery或许Music这样的运用中包括它们。
假如你想要保存与你的运用没有相关的文件,而且这些文件不应在运用卸载时被删去,把他们保存在外部存储的一个公共目录上即可。这些目录坐落外部存储的根目录下,比方Music/, Pictures/, Ringtones/,以及其它目录。
在API Level 8或许更高版别,调用getExternalStoragePublicDirectory(),传递你需求的公共目录的类型,比方DIRECTORY_MUSIC, DIRECTORY_PICTURES, DIRECTORY_RINGTONES或许其它。如有必要,这个办法会创立新目录。
假如你正在运用API Level 7或许更低版别,调用getExternalStorageDirectory()翻开一个File,它表明外部存储的根目录。接着保存你的同享文件在以下文件夹之一:
Music/ – 媒体扫描器把一切在此发现的媒体归类为用户的音乐。
Podcasts/ – 媒体扫描器把一切在此发现的媒体归类为播客。
Ringtones/ – 媒体扫描器把一切在此发现的媒体归类为铃声。
Alarms/ – 媒体扫描器把一切在此发现的媒体归类为闹铃。
Notifications/ – 媒体扫描器把一切在此发现的媒体归类为提示音。
Pictures/ – 一切相片(相机拍照的在外)。
Movies/ – 一切影片(摄像机拍照的在外)。
Download/ – 各类下载。
保存缓存文件
假如你正在运用API Level 8或许更高版别,调用getExternalCacheDir()翻开一个File,它表明你的运用应当保存文件地点的外部存储目录。假如用户卸载了你的运用,这些文件会被主动删去。可是,在你的运用的生命周期中,你应当办理这些缓存文件以及删去其间过期的部分以确保文件空间。
假如你正在运用API Level 7或许更低版别,运用getExternalStorageDirectory()翻开一个File,它表明外部存储的根目录。接下来,你应当写入你的数据在一下目录:
/Android/data//files/
com.example.android.app。
运用数据库 – Using Databases
Android供给了对SQLite数据库的完好支撑。你创立的任何数据库都能被运用程序中的恣意类经过数据库名拜访。可是不行以在运用程序以外拜访。
引荐的创立新的SQLite数据库的办法是,在你履行SQLite指令在数据库中创立表的时分,创立一个SQLiteOpenHelper的子类,并重写onCreate()办法。例如:
class extends { static int DATABASE_VERSION ; static String DICTIONARY_TABLE_NAME ; static String DICTIONARY_TABLE_CREATE + DICTIONARY_TABLE_NAME ( + + KEY_DEFINITION TEXT);DictionaryOpenHelperContext context{ (context, , DATABASE_VERSION} public () .execSQL); }
接着,你能够运用结构办法获得你完成的SQLiteOpenHelper的一个实例。别离运用getWritableDatabase()和getReadableDatabase()读写数据库。两者都会回来一个SQLiteDatabase目标,代表那个数据库,并供给操作SQLite的办法。
Android没有在规范SQLite概念之外加以任何约束。咱们主张包括一个自增值的主键字段,能够作为一个仅有的ID,以便快速定位一条记载。这对私有数据来说不是有必要的。但假如你完成了一个content provider,就有必要包括一个仅有的ID,它运用BaseColumns._ID常量。
你能够运用SQLiteDatabase.query()办法履行SQLite查询,这个办法承受各种查询参数,例如待查询的表、投影、挑选、列、组,或许其他。关于杂乱查询,比方一些需求用到列的别号的,你应当运用SQLiteQueryBuilder,它能供给一些适宜的办法以创立查询。
每一个SQLite查询都会回来一个Cursor目标,指向查询得到的一切行。Cursor目标总是你用来获得数据库查询或许读取行或列的成果的途径。
关于示例运用中演示如安在Android中运用SQLite数据库,见Node Pad和Searchable Dictionary这两个运用。
数据库调试
Android SDK包括了一个sqlite3的数据库东西,答应你阅读表内容,运转SQL指令,以及履行其他SQLite数据库中有用的功用。想要了解怎么运转这个东西,请检查Examining sqlite3 databases from a remote shell这个比方。
运用网络连接 – Using a Network Connection
你能够运用网络连接(当可用时)经过根据web的服务存储或获得数据。需求履行网络操作时,运用以下包中的类:
java.net.*
android.net.*