Android 存储选择

来源:互联网 发布:淘宝搜索接口api 编辑:程序博客网 时间:2024/06/05 15:42

以下内容翻译自Android开发文档 Storage Options 篇,如有错误或不当之处,欢迎指出。

---------------------------------------------------------------------------------------------------------------------

Android提供了多种选择来存储持久的应用数据。你可以根据自身需求选择相应的存储方式,比如数据是否私有的,或者可以被其他应用(或用户)访问,以及你的数据需要的空间。

  • Shared Preferences:用键值对的方式存储私有的基本的数据
  • Internal Storage:存储在设备内存私有数据
  • External Storage:存储在可共享的外存上的公共数据
  • SQLite Databases:存储在私有数据库的结构化数据
  • Network Connection:存储在自己的网络服务器的数据 
    Android还提供了一种方式将你的私有数据暴露给别的应用——content provider

使用Shared Preferences

SharedPreferences类提供了通用框架来允许你保存和检索基础数据类型的永久键值对。你可以使用SharedPreferences阿狸保存基本数据:booleansfloatsintsstrings。这些数据将会随着用户会话一直保存,即使进程被杀掉(除非用户手动清除数据,或者卸载应用)。 
获取SharedPreferences对象,可以使用如下两种方法:

  • getSharedPreferences():当你需要多个preferences文件时,使用这个方法,并在第一个参数中命名你的文件
  • getPreferences():当你只需要一个preferences文件时,使用这个方法,会使之成为唯一的preferences文件,你不需要提供名字。 
    写入数据:
  1. 调用edit()方法来获取一个SharedPreferences.Editor
  2. 调用诸如putBoolean()putString()方法来写入数据
  3. 调用commit()方法提交新的数据 
    读取数据,使用SharedPreferences的方法,诸如getBoolean()getString()等。 
    下面的例子时保存计算器的静音模式设置
public class Calc extends Activity {    public static final String PREFS_NAME = "MyPrefsFile";    @Override    protected void onCreate(Bundle state){       super.onCreate(state);       . . .       // Restore preferences       SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);       boolean silent = settings.getBoolean("silentMode", false);       setSilent(silent);    }    @Override    protected void onStop(){       super.onStop();      // We need an Editor object to make preference changes.      // All objects are from android.context.Context      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);      SharedPreferences.Editor editor = settings.edit();      editor.putBoolean("silentMode", mSilentMode);      // Commit the edits!      editor.commit();    }}

使用the Internal Storage

你可以直接将数据保存在设备的内存中。Android默认保存在内存中的文件是你的应用私有的,其他应用不能访问(包括用户)。当用户卸载应用时,这些文件也会被删除。 
创建和写入内存中的私有文件方法

  1. 调用openFileOutput()方法,传入文件名和操作模式。这个方法会返回一个FileOutputStream
  2. 调用write()方法写入文件
  3. 调用close()方法关闭流 
    举个例子:
String FILENAME = "hello_file";String string = "hello world!";FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);fos.write(string.getBytes());fos.close();

从内存中读取文件

  1. 调用openFileInput()方法,并传入要读取的文件名。这个方法将会返回一个FileInputStream
  2. 调用read()方法读取字节
  3. 调用close()方法关闭流

    Tips:当你想要在编译时在你的应用中保存静态文件,将文件保存在项目的res/raw/目录中。你可以使用openRawResource()方法传入资源IDR.raw.<filename>来打开该文件。这个方法会返回一个InputStream`用来读取文件(但你不能写入原始文件)。

保存缓存文件

当你想要缓存某些数据时,比起永久保存,你可以使用getCacheDir()方法来打开应用用来存储临时缓存文件的目录下的一个文件。 
当设备内存空间不足时,Android可能会删除这些缓存文件来恢复空间。但是你不能以来系统为你清理这些文件。你应该时不时的清理下你的缓存文件,使之保持在内存消费的合理限制中,比如1MB。当用户卸载应用时,这些文件将会被删除。

其他可用的方法

  • getFilesDir():获取你的内部文件所在的文件系统目录的绝对路径
  • getDir():创建一个(或打开一个已经存在的)位于你的内存空间的目录
  • deleteFile():删除保存在内存中的文件
  • fileList():返回当前由你的应用保存的文件列表

使用the External Storage

每台Android兼容的设备都支持一个可共享的external storage方便你存储文件。它可以时可移除的存储媒介(比如一张SD卡)或者内存(不可移除的)。保存在外存中的文件是全世界可读的,并且当它们启用USB大容量存储在计算机上传输文件时,它们可以被用户修改。

注意:当用户在计算机上mount外存或者移除媒介时,外存会变成不可用状态,你保存到外存的文件上也并没有安全保证。所有应用可以读写外存中的文件,用户也可以移除它们。

获取访问外存权限

要在应用中读写外存中的文件,你需要READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE系统许可。如下:

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

检查媒介可用性

在对外存进行操作前,你总是需要调用getExternalStorageState()方法来检查媒介是否可用。媒介可能正挂载在一台计算机上,丢失、只读或者其他状态。如下所示,这里由集中你可以用来检查可用性的方法:

/* Checks if external storage is available for read and write */public boolean isExternalStorageWritable() {    String state = Environment.getExternalStorageState();    if (Environment.MEDIA_MOUNTED.equals(state)) {        return true;    }    return false;}/* Checks if external storage is available to at least read */public boolean isExternalStorageReadable() {    String state = Environment.getExternalStorageState();    if (Environment.MEDIA_MOUNTED.equals(state) ||        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {        return true;    }    return false;}

保存可以分享给其他应用的文件

通常,用户从你的应用获取的新的文件应该被保存在公共的位置,以便其他应用可以访问,用户可以轻易拷贝。此时,你应该使用可共享的公共目录,比如Music/Pictures/Rintones/等。 
调用getExternalStoragePublicDirectory(),传入你想要的目录类型,比如DIRECTORY_MUSICDIRECTORY_PICTURESDIRECTORY_RINGTONES,或其他。通过将文件保存到相应的媒体类型目录下,系统的媒体扫瞄器可以将你的文件适当归类。 
如下提供了一个在公共的图片目录下创建一个新的相册目录的方法:

public File getAlbumStorageDir(String albumName) {    // Get the directory for the user's public pictures directory.    File file = new File(Environment.getExternalStoragePublicDirectory(            Environment.DIRECTORY_PICTURES), albumName);    if (!file.mkdirs()) {        Log.e(LOG_TAG, "Directory not created");    }    return file;}

保存应用私有的文件

如果你要处理一些不打算被其他应用使用的文件(比如只能用在你的应用中的图片、音效等),你应该调用getExternalFilesDir()方法来创建(或打开)外存中的私有存储目录。该方法还需要一个type参数来标识你的子目录类型(比如DIRECTORY_MOVIES)。如果你不需要标识媒体目录,传入null即可。 
从Android 4.4.开始,读写应用的私有目录不许再添加READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE许可。因此,你只需在低版本中声明该许可:

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

注意:当用户卸载你的应用时,该目录和它的所有内容都会被删除。同时,系统的媒体扫描器不再读取该目录下的文件,隐藏它们不能被MediaStorecontent provider访问。

有时候,设备分类了一部分内存来使用,同时外存也提供了SD卡槽。当一个设备运行的是Android 4.3或者更低,getExternalFilesDir()方法只能访问内存部分而不能读写SD卡。从Android 4.4开始,你可以通过调用getExternalFilesDirs()方法访问这两个位置,它会各返回一个文件列表。列表中的第一个条目就是主要的外存,你可以使用这个位置除非它满了或者不可用。如果你想要访问两个位置且又要支持Android 4.3及以下版本的,那么可以使用support library的静态方法:ContextCompat.getExternalFilesDirs()。它也会返回一个文件列表,但在Android 4.3及以下版本中,只包含一个条目。

注意:尽管这些目录由getExternalFilesDir()提供,且不能被MediaStorecontent provider访问,但是其他带有READ_EXTERNAL_STORAGE许可的应用可以访问外存的所有文件,包括这些目录。如果你要完全限制对你的文件的访问,你应该将文件写入内存中。

保存缓存文件

要打开一个外存目录中你用来存储缓存文件的File,调用getExternalCacheDir()方法。如果用户卸载了你的应用,这些文件会被自动删除掉。 
类似ContextCompat.getExternalFilesDirs(),上面的方法,你也可以通过调用ContextCompat.getExternalCacheDirs()方法来访问位于第二外存(如果可以用)中的缓存目录。

Tips:为了保留文件空间和保持应用性能,小心地管理缓存文件并且一旦不需要了就及时移除它们是很重要的。


使用Databases

Android提供了对SQLite数据库的完整支持。你在应用中创建的所有数据库,你都可以使用数据库名在任意类中访问,但不能在应用外访问。 
推荐的创建SQLite数据库的方法是创建一个SQLiteOpenHelper的子类,并且重写onCreate()方法,在该方法中你可以执行SQLite命令来创建数据库表。举个例子:

public class DictionaryOpenHelper extends SQLiteOpenHelper {    private static final int DATABASE_VERSION = 2;    private static final String DICTIONARY_TABLE_NAME = "dictionary";    private static final String DICTIONARY_TABLE_CREATE =                "CREATE TABLE " + DICTIONARY_TABLE_NAME + " (" +                KEY_WORD + " TEXT, " +                KEY_DEFINITION + " TEXT);";    DictionaryOpenHelper(Context context) {        super(context, DATABASE_NAME, null, DATABASE_VERSION);    }    @Override    public void onCreate(SQLiteDatabase db) {        db.execSQL(DICTIONARY_TABLE_CREATE);    }}

然后你可以获取你的SQLiteOpenHelper子类的实例。分别调用getWritableDatabase()getReadableDatabase()方法来读、写数据库。它们都返回一个SQLiteDatabase对象,它表示你要操作的那个数据库并提供了SQLite操作的相关方法。 
你可以使用SQLiteDatabasequery()方法来执行SQLite查询,它需要一些查询参数,诸如表名、projectionselectioncolumnsgrouping,及其他。对于复杂的查询,比如那些需要字段别名的,你应该使用SQLiteQueryBuilder,它提供了多种方便的方法来创建查询语句。 
每个SQLite查询会返回一个Cursor指向本次查询找到的行。Cursor是一种你可以从数据库查询中导航结果和读取行列的机制。

数据库调试

Android SDK包含了sqlite3数据库工具,允许你浏览表的内容,执行SQL命令,以及其他在SQLite数据库中很有用的方法。

0 0
原创粉丝点击