Android Developers:存储选项

Android 为你提供了几种保存持久应用程序数据方式。你所选择的方法取决于你的特定需求,例如数据是否是你的应用程序私有的或者允许其他程序(和用户)访问,和你的数据需要多大的存储空间。 
 

你的数据存储方式如下 

Shared Preference 

以键值对的形式存储简单私有的数据 

Internal Storage 

在设备的内存中存储私有数据 

External Storage 

在共享的外部存储上存储共有的数据 

SQLite Storage 

在私有数据中存储结构化数据 

Network Connection 

在自己的网络服务器的web上存储数据 

 
Android为你提供了一种向其他的程序暴露你私有数据的方式---使用content provider。content provider是一个可选的组件,它暴露你的程序数据的读写权限,不受任何限制。关于更多使用content providerde的信息,请阅读Content Providers文档 

 

使用Shared Preferences 

—————————————————————————————————————————

Android 为你提供了几种保存持久应用程序数据方式。你所选择的方法取决于你的特定需求,例如数据是否是你的应用程序私有的或者允许其他程序(和用户)访问,和你的数据需要多大的存储空间。 
 

你的数据存储方式如下 

Shared Preference 

以键值对的形式存储简单私有的数据 

Internal Storage 

在设备的内存中存储私有数据 

External Storage 

在共享的外部存储上存储共有的数据 

SQLite Storage 

在私有数据中存储结构化数据 

Network Connection 

在自己的网络服务器的web上存储数据 

 
Android为你提供了一种向其他的程序暴露你私有数据的方式---使用content provider。content provider是一个可选的组件,它暴露你的程序数据的读写权限,不受任何限制。关于更多使用content providerde的信息,请阅读Content Providers文档 

 

使用Shared Preferences 

————————————————————————————————————————————— 

SharedPreferences类提供了一个通用的框架,它允许你保存和获取原始数据类型的持久化键值对。你可以使用SharedPreferences去保存任何原始数据:booleans,floats,ints,longs,和strings。这些数据将会跨越用户会话保存(即使你的程序被杀死)。 

 

你的程序为了获取SharedPreferences对象,使用以下两个方法中的任意一个 

  • getSharedPreferences() - 如果你需要多个preferences文件的时候就使用它。你使用第一个参数指定它们的名字来加以区分 

  • getPreferences() - 如果你仅仅需要一个preference文件的时候使用它,该文件与你的Activity关联。因为这种方法仅仅有一个与你Activity关联的preference文件,你不需要提供名字。 

 

写数据 

     1.调用edit()获取SharedPreferences.Editor对象 

     2.使用例如putBoolean()和putString()等方法添加值 

     3.使用commit()方法提交新的值 

 

读数据,使用例如getBoolean()和getString()等SharedPreferences的方法 

 

用户偏好:Shared preferences不仅仅保存“用户偏好”,例如用户选择了什么手机铃声。如果你对为你的应用程序创建用户偏好感兴趣,查阅PreferenceActivity,它为你提供了一个Activity框架,来创建用户偏好,它将会自动存储(使用Shared preferences)。 

 

以下是一个实例,它在计算器中保存一个silent keypress模式的共享参数 

 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(); 
    } 
} 
使用内部存储器  

————————————————————————————————————————————— 

你可以将文件直接保存在设备的内部存储器中。默认情况下,保存在内部存储器中的文件是你的程序私有的,并且其他的程序无法访问(用户也一样)。当用户卸载你的程序的时候,文件也被移除 

      

向内部存储器创建和写一个私有文件 

     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(); 
MODE_PRIVATE创建一个新的文件(或替换一个同名的文件),它是你的程序私有的。其它可用的模式有:MODE_APPEND,MODE_WORLD_READABLE,和MODE_WORLD_WRITEABLE。  

 

从内部存储器中读取文件 

     1. 传递需要读取的文件名称为参数调用openFileInput()。然会一个FileInputStream对象 

     2.调用read()方法从文件中读取字节 

     3.调用close()方法关闭文件流 

提示:如果你想在程序编译的时候保存一个静态的文件,将它保存在你的项目res/raw/ 目录下。你能调用openRawResource()方法打开它,传入资源IDR.raw.<filename>为参数。这个方法返回一个InputStream对象,它可以使你能够读取文件[一般为音频、视频等文件、Html、APK文件等]但是你不能写这个文件)。   

 

保存缓存 

如果你想缓存一些数据,而不是持久化存储,你可以调用getCacheDir()方法打开一个File对象,它代表了你的应用程序存储临时缓存文件的内部路径。当设备在内存空间稀缺的时候,Android可能会删除这个缓存文件去回收存储空间。然而,你不能依靠系统去为你清除这个文件。你应该常常自己维护这个文件,并且保持在一个合理的大小限制以内,例如1MB。当用户卸载应用程序的时候,这个文件被移除。 

 

别的有帮助的方法 

     getFileDir():获取你的内部文件存储的文件系统目录的绝对路径 

     getDir():在你的内部存储空间创建(或者打开一个已存在)的目录 

     deleteFile():删除一个存储在内部空间的文件 

     fileList():返回你的应用程序当前存储文件的数组 

 

使用外部存储 

————————————————————————————————————————————— 

每个兼容Android的设备都支持一个共享“外部存储”,你能使用它来保存文件。它可以是一个可移除的存储媒介(例如一个SD卡)或者一个内在的(不可移除)存储。当它们从USB大量存储传输到电脑中的时候,存储在外部存储的文件都是任何人可读的,并且可以被用户修改。 

 

一台设备使用部分内部存储用于外部存储是可能的,也会提供一个SD卡槽。如果这样,SD卡不是外部存储的一部分,并且你的应用部不能访问它(系统无法检测)外部存储被定义仅仅为用户提供系统扫描到的媒介)。 

 

当心:如果用户在一台电脑挂载或者移除媒介,外部存储会变得不不可用,并且你存储在外部存储的文件没有安全保障。所有的程序都能读写在外部存储上的文件,并且用户可以删除它。 

 

检测媒介的可用性 

在你使用外部存储做任何工作之前,你必须调用getExternalStorageState()去检查这个媒介是否可用。这么媒介可能被挂载在一台电脑,丢失,只读,或者在别的某种状态。例如,以下是你如何检查可用性的案例 

 boolean mExternalStorageAvailable = false; 
 boolean mExternalStorageWriteable = false; 
 String state = Environment.getExternalStorageState(); 
 
if (Environment.MEDIA_MOUNTED.equals(state)) { 
    // We can read and write the media 
    mExternalStorageAvailable = mExternalStorageWriteable = true; 
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { 
    // We can only read the media 
    mExternalStorageAvailable = true; 
    mExternalStorageWriteable = false; 
} else { 
    // Something else is wrong. It may be one of many other states, but all we need 
    //  to know is we can neither read nor write 
    mExternalStorageAvailable = mExternalStorageWriteable = false; 
} 
这个案例是检查外部存储是否可以读写。getExternalStroageState()方法返回一个你检测到的状态,例如媒介是否共享(连接到一台电脑),完全丢失(已经移除)等。当你的应用程序需要访问这个媒介的时候,你可以使用这些信息通知用户  

 

访问外部存储的文件 

如果你使用API Level 8以及以上的版本,使用getExternalFilesDir()去打开一个File对象,它代表了你存储你的文件的外部存储的路径。这个方法使用一个类型参数,它指定了你想操作的子目录的类型,例如DIRECTORY_MUSIC和DIRECTORY_RINGTONES(传递Null,则返回你的应用程序的文件目录的根)。如果有必要,这个方法将创建一个合适的路径。通过指定目录的类型,你确保了Android的媒体扫描器在系统中能正确的将你的文件分类(例如,铃声被定义为铃声而不是音乐)。如果用户卸载你的应用程序,该目录和所有的内容将被删除 

 
如果你使用API Level 7或者更低的版本,使用getExternalStorageDirectory(),去打开一个File对象,它代表了外部存储的根目录。那么你将要把你的数据写在如下目录中 

      /android/data/<package_name>/files/ 

 

<package_name>是你的java包名,例如”com.example.android.app”。如果这个设备正在运行的是API Level 8以及以上的版本,那么他们卸载你的应用程序的时候,这个目录以及所有的内容都将被删除(API Level 8之前不会被删除?)。 

 

保存共享文件 

如果你想保存文件,他们不仅仅特定于你的程序,并且当你的程序被卸载时不被删除,将它们保存在外部存储上的一个公共目录中。这些目录在放在外部存储的根,例如Music/,Pictures/,Ringtones/,和其他 

 

如果你使用API Level7或更低的版本,使用getExternalStorageDirectory()方法获取一个File对象,它代表了外部存储的根,然后将你的共享文件存储在以下的目录之一 

     Music/ -媒体扫描器将所有从这里找到的文件视为音乐 

     Podcasts/ -媒体扫描器将所有从这里找到文件视为播客 

     Ringtones/ -媒体扫描器将所有从这里找到文件视为铃声 

     Alarms/ -媒体扫描器将所有从这里找到文件视为警告 

     Notifications/ -媒体扫描器将所有从这里的找到的文件视为通知铃声 

     Pictures/ -所有的照片(包括照相机拍摄的 

     Movies/ -所有的电影(包括录像机录制的 

     Download/ -其它的下载 

对媒体扫描器隐藏你的文件 

在你的外部文件目录中包含一个被命名为.nomedia的空文件(注意在文件名中的点)。这将阻止Android的媒体扫描器读取你的媒体文件,和在如Gallery或者Music的应用中包含它们 

 

保存缓存文件 

如果你使用API Level 8或者更高的版本,使用getExternalCacheDir()打开一个File对象,它代表了你保存缓存文件的外部存储的路径如果用户卸载你的应用程序,这些文件将会被自动删除。然而,在你的程序的生命周期,你应该管理这些缓存文件,并且为了维护文件空间,在它们不需要的时候删除它们。 

      

如果你使用API Level 7或者更低的版本,使用getExternalStroageDirectory()代开一个File对象,它代表了外部存储的根目录,然后你在这个目录里面写你的缓存数据 

     /Android/data/<package_name>/cache/ 

<package_name>是你的包名,如”com.example.android.app”。 

 

使用数据库 

————————————————————————————————————————————— 

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对象,它代表数据库并且提供了操作数据库的方法  

 

你可以使用SQLiteDatabase的query()方法执行数据库的查询操作,它接受各种各样的查询参数,例如表查询,选择查询,行查询,组查询和其他。对于更复杂的查询,例如需要列别名的查询,你需要使用SQLiteQueryBuilder,它提供了几个方便查询的方法。 

      

所有的SQLite查询都返回一个Cursor,它查询到的所有的行。Cursor是一种操纵机制,它负责操作你从数据库查询的结果,如读取行和列。 

      

查看Note Pad和Searchable Dictionary示例程序,它们演示了在Android中如实使用SQLite数据库 

 

数据库调试 

Android SDK提供了包括sqlite3数据库工具,它使你能够浏览表的内容,运行SQL命令,和运行在SQLite数据中其它重要的功能。查看Examining sqlite3 data frome shell去学习如何使用这个工具 

 

使用网络连接 

————————————————————————————————————————————— 

你可以使用网络(当它可用的时候)在自己的web服务器上存储和获取数据。执行网络操作,使用下面包中的类 

     java.net.*; 

     android.net.* 

你可能感兴趣的:(android,Data,storage,options,developers)