android数据保存

永久保存数据的方法:
1.Shared Preferences 以键值对的形式存储基本数据类型( booleans, floats, ints, longs, and strings),存储的数据在限制在一个application(一个package)内部使用
 
2.Internal Storage 将私有文件存储到内部存储器中。这些文件是一个application私有的,其他application无法访问到
3.External Storage 将公共数据存储到外部存储器中

4.SQLite Databases
Store structured data in a private database.
5.Network Connection
Store data on the web with your own network server.
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

Using Shared Preferences
获取一个 SharedPreferences对象,两种方法:

getSharedPreferences() - 有多个 preferences files 时使用该方法。该方法的第一个参数指定想要操作的preferences file 的名字
getPreferences() - 只有一个preferences file时使用该方法。Because this will be the only preferences file for your Activity, you don't supply a name.
获取对象之后,就可以调用对象的方法读取preferences file中的数据和写入数据到preferences file

读取: 使用 SharedPreferences 的 getBoolean() 和getString()方法

写入:

调用 edit() 方法获取 SharedPreferences.Editor对象.
使用 putBoolean() and putString()写入值.
Commit the new values with commit() :使用该方法提交新写入的值
看下面的示例:

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();    
    }    
}  
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
私有文件的存储。用户卸载application后该种数据会被移除

将私有文件写入到内存中:

调用 openFileOutput() 方法获取文件的输出流。在方法的参数中指定文件名和操作模式
使用 write()方法写入
关闭流: close().
示例:

view plaincopy to clipboardprint?
String FILENAME = "hello_file";    
String string = "hello world!";    
     
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);    
fos.write(string.getBytes());    
fos.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.

从内存中读取文件到程序中:

调用openFileInput() 方法获取输入流。方法参数指定文件名
使用read()方法读取.
关闭流: close().
在编译期读取只读的静态文件:

要把文件放在 res/raw/目录下, 使用openRawResource(R.raw.<filename>)方法打开文件,该方法返回一个输入流,使用这个流就可以读取文件内容了

Saving cache files

如果只想暂时性的保存数据而不是长久保存

使用 getCacheDir() 方法打开一个 File (application存放临时缓存数据的路径)

当设备内存不足时,系统可能会自动删除这类数据以释放内存空间。但是你不能依靠这个可能性,你要保证cache文件不能占用过多的内存空间。当application被卸载,这部分数据被移除

Other useful methods
getFilesDir()
Gets the absolute path to the filesystem directory where your internal files are saved.
获得基于存储 internal files 目录的完整路径(不同的文件系统获得路径会不同)
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.
获得一个application存储的所有文件,并存储在数组中
Using the External Storage
外部存储。这些文件可以在设备之间随意的读写,只要设备的系统与android兼容。容易丢失,所以操作的时候要格外小心

用于存储的storage有:可移动的media storage(如SD卡)和不可移动的storage
 
Checking media availability
检查media是否可用

media在使用之前要先检查是否可用,调用 getExternalStorageState()方法获取media的状态。用法如下:

view plaincopy to clipboardprint?
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;    
}  
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; 
}

一般常见的状态有:可读写、只读和不可用

getExternalStorageState()还会返回其他更多的状态,比如media有没有共享、安装是否正常、卸载时是否出错等等,以此来通知用户设备的状态

Accessing files on external storage
当你使用Level8或更高的API时, 使用getExternalFilesDir() 打开一个 File (表示external storage中本次数据存储的目录)。

不传递参数时表示external storage的根目录。有参数则对应着指定的目录类型,例如 DIRECTORY_MUSIC and DIRECTORY_RINGTONES,分别代表音乐目录和铃声目录。如果指定的目录不存在,就会创建该目录。通过指定目录类型可以让android 多媒体扫描器给你的文件分类。如果你的application被用户卸载,这种方式存储的目录和内容会被移除

如果使用Level7或更低版本的API,使用 getExternalStorageDirectory(), 打开 File所代表的external storage的根目录。

还需要把数据写在下面的目录中:/Android/data/<package_name>/files/用户使用Level8或更高 版本的API卸载这个版本的应用时,上面的目录和目录中的内容会被移除Saving files that should be shared
如 果想保存与应用无关的文件,也就是说application卸载后保存的文件仍然保留,就要把文件保存在 external storage的公共目录中,这些目录位于 external storage的根目录,比如 Music/, Pictures/, Ringtones/等

当你使用Level8或更高的API时,使用 getExternalStoragePublicDirectory()方法,传递参数 DIRECTORY_MUSIC, DIRECTORY_PICTURES, DIRECTORY_RINGTONES,就可以把文件保存在指定目录。目录不存在则创建

如果使用Level7或更低版本的API, 使用 getExternalStorageDirectory() 方法打开 File 所代表的 external storage的根目录, 把共享文件存储到下面的目录中一个即可:

Music/ - Media scanner classifies all media found here as user music.
Podcasts/ - Media scanner classifies all media found here as a podcast.
Ringtones/ - Media scanner classifies all media found here as a ringtone.
Alarms/ - Media scanner classifies all media found here as an alarm sound.
Notifications/ - Media scanner classifies all media found here as a notification sound.
Pictures/ - All photos (excluding those taken with the camera).
Movies/ - All movies (excluding those taken with the camcorder).
Download/ - Miscellaneous downloads.
Saving cache files
如同上面提到的,根据不同的API版本使用不同的方法:

高版本API: 使用getExternalCacheDir()

低版本API: getExternalStorageDirectory()打开根目录,cache data 写到/Android/data/<package_name>/cache/目录中

Using Databases
android完全支持SQLite数据库

经典的创建SQLite数据库的方法是:构造SQLiteOpenHelper 的子类并覆盖onCreate()方法,就可以在方法中使用SQLite命令:

public class MyDbOpenHelper 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);    
    }    
}  
public class MyDbOpenHelper 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); 
    } 
}

Android中使用SQLite 数据库的例子参见 Note Pad 和Searchable Dictionary 。

Android中SQLite 数据库的调试工具:sqlite3

Using a Network Connection
You can use the network (when it's available) to store and retrieve data on your own web-based services. To do network operations, use classes in the following packages:

java.net.*
android.net.*

posted @ 2015-06-02 16:21  星辰之力  阅读(800)  评论(0编辑  收藏  举报