Android api 数据的保存方式

由于要用到关于保存图片的问题,所以就顺便翻译一下api文档中的这篇文章了。

Storage Options

STORAGE QUICKVIEW

  • Use Shared Preferences for primitive data
  • Use internal device storage for private data
  • Use external storage for large data sets that are not private
  • Use SQLite databases for structured storage

IN THIS DOCUMENT

  1. Using Shared Preferences
  2. Using the Internal Storage
  3. Using the External Storage
  4. Using Databases
  5. Using a Network Connection

SEE ALSO

  1. Content Providers and Content Resolvers

Android provides several options for you to save persistent application data. The solution you choose depends on your specific needs, such as whether the data should be private to your application or accessible to other applications (and the user) and how much space your data requires.

Your data storage options are the following:

Shared Preferences
Store private primitive data in key-value pairs.
Internal Storage
Store private data on the device memory.
External Storage
Store public data on the shared external storage.
SQLite Databases
Store structured data in a private database.
Network Connection
Store data on the web with your own network server.

Android提供了几种选择给我们来保存现在应用的数据,你所选择的方法取决于你确切的需求,例如你的数据是否是对你的应用是私密的,还是对其他的应用也是可以得到的,和你所存储的数据需要多大的空间。

你的数据存储有以下几种选择

Shared Preferences

以键值对的形式存储我们的私密数据。

内部存储

将数据保存在设备的存储空间

外部空间

将数据保存在外部的可存储分享设备上

sql数据库

保存一些有组织结构的私密数据

网络连接

保存一些网页上的数据到你的网络服务器中。

Android provides a way for you to expose even your private data to other applications — with a content provider. A content provider is an optional component that exposes read/write access to your application data, subject to whatever restrictions you want to impose. For more information about using content providers, see the Content Providers documentation.

Android本身提供了一个方法帮助你去将自己私密的数据暴漏给其他的应用通过content provider,一个content provider 是一个可选择的组件用来暴露读写我们应用数据的权利,根据我们自己定制的数据暴露的限制。

Using Shared Preferences


The SharedPreferences class provides a general framework that allows you to save and retrieve persistent key-value pairs of primitive data types. You can use SharedPreferences to save any primitive data: booleans, floats, ints, longs, and strings. This data will persist across user sessions (even if your application is killed).

To get a SharedPreferences object for your application, use one of two methods:

  • getSharedPreferences() - Use this if you need multiple preferences files identified by name, which you specify with the first parameter.
  • getPreferences() - Use this if you need only one preferences file for your Activity. Because this will be the only preferences file for your Activity, you don't supply a nameSharePreferences类提供了一个综合的框架它允许我们保存和查询一些现在的一些简单的数据类型的键值对,你可以利用SharedPreferences来保存的数据类型有,Boolean,floats,ints等。这些数据将会通过用户的sessions存留,尽管你的应用被kill掉了。为你的应用获得sharedPreference对象,可以使用下面两种方法:getSharedPreferences(),如果你需要一个多参数通过名字进行的确认的文件,你可以通过第一个参数进行确认。getpreferences()如果你的activity仅仅只需要一个参数文件使用这个方法,以为这个将会是唯一的参数文件对你的activity,你不能够为其提供一个名字。

下面是代码实例:

To write values:

  1. Call edit() to get a SharedPreferences.Editor.
  2. Add values with methods such as putBoolean() and putString().
  3. Commit the new values with commit()

To read values, use SharedPreferences methods such as getBoolean() and getString().

Here is an example that saves a preference for silent keypress mode in a calculator:

1.通过edit()方法得到一个sharedPreferences.Editor

2.添加一个值比如putBoolean()等

3.置入新的值通过commit()方法。

要读取一些值得话,可以通过getBoolean()等方法。

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();
    }
}

Using the Internal Storage


You can save files directly on the device's internal storage. By default, files saved to the internal storage are private to your application and other applications cannot access them (nor can the user). When the user uninstalls your application, these files are removed.

你可以直接将文件保存在设备内部的存储空间中,默认的,文件将会被保存到内部存储空间,对你的应用是私密的和其它的应用是不能够获取到他们的,当用户卸载掉应用之后数据将会被删除。

创建一个私密文件夹并写进去数据。

To create and write a private file to the internal storage:

  1. Call openFileOutput() with the name of the file and the operating mode. This returns a FileOutputStream.
  2. Write to the file with write().
  3. Close the stream with close().

For example:

String FILENAME = "hello_file";
String string = "hello world!";

FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();

MODE_PRIVATE will create the file (or replace a file of the same name) and make it private to your application. Other modes available are: MODE_APPENDMODE_WORLD_READABLE, and MODE_WORLD_WRITEABLE.

MODE_PRIVATE 将会创建一个文件(或者是取代同名的文件)然后让这个文件成为对你的应用私密的,其它的可用的模式还有:

MODE_APPENDMODE_WORLD_READABLE, and MODE_WORLD_WRITEABLE.

从内部存储空间读取一个文件

To read a file from internal storage:

  1. Call openFileInput() and pass it the name of the file to read. This returns a FileInputStream.
  2. Read bytes from the file with read().
  3. Then close the stream with close().

Tip: If you want to save a static file in your application at compile time, save the file in your project res/raw/directory. You can open it with openRawResource(), passing the R.raw.<filename> resource ID. This method returns an InputStream that you can use to read the file (but you cannot write to the original file).

如果你想保存一些静态的文件在你的应用中在编译的时间,保存你的文件在你的项目中res/raw的目录下,你可以通过使用openRawResource()来打开文件,通过这些文件的ID来对其进行调用,这个方法将会返回一个输入流来帮助你使用读取文件,但是你不能够向这些文件中写入。

Saving cache files

If you'd like to cache some data, rather than store it persistently, you should use getCacheDir() to open a Filethat represents the internal directory where your application should save temporary cache files.

When the device is low on internal storage space, Android may delete these cache files to recover space. However, you should not rely on the system to clean up these files for you. You should always maintain the cache files yourself and stay within a reasonable limit of space consumed, such as 1MB. When the user uninstalls your application, these files are removed.

保存缓冲文件

如果你希望通过缓存的方式来保存这些数据,而不是长久的将其进行保存,你应该使用getCacheDir()方法来实现去打开一个文件在这里你的应用应该保存一些暂时的缓存文件。

Other useful methods

getFilesDir()
Gets the absolute path to the filesystem directory where your internal files are saved.
getDir()
Creates (or opens an existing) directory within your internal storage space.
deleteFile()
Deletes a file saved on the internal storage.
fileList()
Returns an array of files currently saved by your application.
一些方法

getFileDir(),获得一个绝对路径到达你内部文件存储的目录下。

getDir(),在你的存储空间中创造一个目录。

deleteFile(),删除你在内部存储空间保存的文件。

fileList(),返回一个通过你的应用保存的文件的数组。

Using the External Storage

任何一个Android兼容的设备都是支持外部存储,你可以用来保存文件,这个可以是可移动的存储,比如说是sd卡,或者是不可拆卸的内部存储设备,文件存储在外部是可读的,而且可以被用户通过usb大容量存储转化修改在电脑上。

Every Android-compatible device supports a shared "external storage" that you can use to save files. This can be a removable storage media (such as an SD card) or an internal (non-removable) storage. Files saved to the external storage are world-readable and can be modified by the user when they enable USB mass storage to transfer files on a computer.

Caution: External storage can become unavailable if the user mounts the external storage on a computer or removes the media, and there's no security enforced upon files y ou save to the external storage. All applications can read and write files placed on the external storage and the user can remove them.

注意:外部存储设备可能变成不可用,如果用户将外部存储设备在电脑上进行加载或者说移除文件,这就是我们将其保存在外部存储设备上不安全的地方,所有的应用都可以读取,修改文件。

Getting access to external storage

In order to read or write files on the external storage, your app must acquire the READ_EXTERNAL_STORAGE orWRITE_EXTERNAL_STORAGE system permissions. For example:

为了从外部存储上读取文件,我们必须要先获得两个权限。

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

If you need to both read and write files, then you need to request only the WRITE_EXTERNAL_STORAGE permission, because it implicitly requires read access as well.

Note: Beginning with Android 4.4, these permissions are not required if you're reading or writing only files that are private to your app. For more information, see the section below about saving files that are app-private.

如果你需要读取文件的和写文件,那么你需要仅仅   WRITE_EXTERNAL_STORAGE这一个权限。

Checking media availability

Before you do any work with the external storage, you should always call getExternalStorageState() to check whether the media is available. The media might be mounted to a computer, missing, read-only, or in some other state. For example, here are a couple methods you can use to check the availability:

在我们使用使用外部存储做任何的工作的时候,我们总是需要调用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;
}


The  getExternalStorageState()  method returns other states that you might want to check, such as whether the media is being shared (connected to a computer), is missing entirely, has been removed badly, etc. You can use these to notify the user with more information when your application needs to access the media.

这个方法返回另一个状态,你可能需要检测的,列入是否连接到电脑,是否丢失或者移除扥等,你可以使用这些去提醒你的用户使用更多的消息当你的应用需要使用这些的时候。

Saving files that can be shared with other apps

Generally, new files that the user may acquire through your app should be saved to a "public" location on the device where other apps can access them and the user can easily copy them from the device. When doing so, you should use to one of the shared public directories, such as Music/Pictures/, and Ringtones/.

保存可以被其它app分享的文件

通常,用户获得一些新的文件可能需要通过你的app应该被保存为公共的位置在你的设备上,其它的app'也可以访问他们,复制他们从设备上,当这么做的时候,我们应该使用一个分享的公用目录。

To get a File representing the appropriate public directory, callgetExternalStoragePublicDirectory(), passing it the type of directory you want, such as DIRECTORY_MUSICDIRECTORY_PICTURES,DIRECTORY_RINGTONES, or others. By saving your files to the corresponding media-type directory, the system's media scanner can properly categorize your files in the system (for instance, ringtones appear in system settings as ringtones, not as music).

为了获得一个代表正确公共目录的文件,我们调用getExternalStoragePublicDirectory()这个方法通过你想得到的目录类型,比如说, DIRECTORY_MUSICDIRECTORY_PICTURES,DIRECTORY_RINGTONES或者是其它的,系统通过扫描会正确的将在系统中的文件夹进行分类整理。

例如这里是一个创建一个目录为一个新的相册,在公共相册的目录。

For example, here's a method that creates a directory for a new photo album in the public pictures directory:

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;
}

Saving files that are app-private

If you are handling files that are not intended for other apps to use (such as graphic textures or sound effects used by only your app), you should use a private storage directory on the external storage by callinggetExternalFilesDir(). This method also takes a type argument to specify the type of subdirectory (such asDIRECTORY_MOVIES). If you don't need a specific media directory, pass null to receive the root directory of your app's private directory.

如果你要处理的文件并不是给其它的app用的,比如图形纹理或者是音效在你的app中,你应该用一个私密的存储目录在外部存储上通过使用方法getExternalFilesDir(),这个方法也带有一个类型内容提要来表明子目录下所存储文件的类型,如果你不需要一个确认的媒体目录,传一个null值接收你app的私密目录下的根目录。

Beginning with Android 4.4, reading or writing files in your app's private directories does not require theREAD_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE permissions. So you can declare the permission should be requested only on the lower versions of Android by adding the maxSdkVersion attribute:

从Android 4.4开始,从你的app私密目录下读写文件不需要READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE这两个权限了,因此你仅需要在一些低版本的Android中加上这些属性。

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

Note: When the user uninstalls your application, this directory and all its contents are deleted. Also, the system media scanner does not read files in these directories, so they are not accessible from the MediaStorecontent provider. As such, you should not use these directories for media that ultimately belongs to the user, such as photos captured or edited with your app, or music the user has purchased with your app—those files should be saved in the public directories.

当你卸载你的app的时候,这个目录和你的内容都会本删除,当然你的系统媒体查看器不能够从这些文件中读取出来,因此它们通过MediaStorecontent provider是不能够获得的,同样的,比如当我们通过我们的app拍的照片或者是编辑的内容,或者是用户在app上购买的音乐,这些文件应该将其存在公共的目录下。

Sometimes, a device that has allocated a partition of the internal memory for use as the external storage may also offer an SD card slot. When such a device is running Android 4.3 and lower, the getExternalFilesDir()method provides access to only the internal partition and your app cannot read or write to the SD card. Beginning with Android 4.4, however, you can access both locations by calling getExternalFilesDirs(), which returns a File array with entries each location. The first entry in the array is considered the primary external storage and you should use that location unless it's full or unavailable. If you'd like to access both possible locations while also supporting Android 4.3 and lower, use the support library's static method,ContextCompat.getExternalFilesDirs(). This also returns a File array, but always includes only one entry on Android 4.3 and lower.

大多时候,一个设备上都会有单独隔离出来的区域作为外部存储,或者有预留的sd卡的卡槽,例如,当我们在Android 4.3或者更低的版本上运行的时候, getExternalFilesDir()这个方法就会提供一个通道,仅仅在你的内部存储的隔离区而且你的app是无法从sd卡上进行读写操作的,在Android 4.4之前,然后你可以得到地址通过调用 getExternalFilesDirs()方法,这个方法将会返回一个文件数组带有把每一个地址的入口,

Caution Although the directories provided by getExternalFilesDir() and getExternalFilesDirs() are not accessible by the MediaStore content provider, other apps with the READ_EXTERNAL_STORAGE permission can access all files on the external storage, including these. If you need to completely restrict access for your files, you should instead write your files to the internal storage.

Saving cache files

To open a File that represents the external storage directory where you should save cache files, callgetExternalCacheDir(). If the user uninstalls your application, these files will be automatically deleted.

Similar to ContextCompat.getExternalFilesDirs(), mentioned above, you can also access a cache directory on a secondary external storage (if available) by calling ContextCompat.getExternalCacheDirs().

Tip: To preserve file space and maintain your app's performance, it's important that you carefully manage your cache files and remove those that aren't needed anymore throughout your app's lifecycle.

Using Databases


Android provides full support for SQLite databases. Any databases you create will be accessible by name to any class in the application, but not outside the application.

The recommended method to create a new SQLite database is to create a subclass of SQLiteOpenHelper and override the onCreate() method, in which you can execute a SQLite command to create tables in the database. For example:

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);
    }
}

You can then get an instance of your SQLiteOpenHelper implementation using the constructor you've defined. To write to and read from the database, call getWritableDatabase() and getReadableDatabase(), respectively. These both return a SQLiteDatabase object that represents the database and provides methods for SQLite operations.

You can execute SQLite queries using the SQLiteDatabase query()methods, which accept various query parameters, such as the table to query, the projection, selection, columns, grouping, and others. For complex queries, such as those that require column aliases, you should use SQLiteQueryBuilder, which provides several convienent methods for building queries.

Every SQLite query will return a Cursor that points to all the rows found by the query. The Cursor is always the mechanism with which you can navigate results from a database query and read rows and columns.

For sample apps that demonstrate how to use SQLite databases in Android, see the Note Pad and Searchable Dictionary applications.



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值