Android四種存儲方式: sharedpreference,file,SQlite,contentprovider。
1、SharedPreferences是一種輕型的數據存儲方式,它的本質是基於XML文件存儲key-value鍵值對數據,通常用來存儲一些簡單的配置信息。其存儲位置在/data/data/<包名>/shared_prefs目錄下。SharedPreferences對象本身只能獲取數據而不支持存儲和修改,存儲修改是通過Editor對象實現。實現SharedPreferences存儲的步驟如下:
一、根據Context獲取SharedPreferences對象
二、利用edit()方法獲取Editor對象。
三、通過Editor對象存儲key-value鍵值對數據。
四、通過commit()方法提交數據。
具體實現代碼如下:實現存儲,讀取,清除,刪除
效果圖:
首先創建:// 首先拿到sharedpreference對象
mShared =getSharedPreferences(SHARED_MAIN_XML, MODE_PRIVATE);
存儲:
savename = name.getText().toString().trim();
saveage = Integer.valueOf(age.getText().toString().trim());
Editor editor = mShared.edit();
editor.putString("name", savename);
editor.putInt("age", saveage);
// 保證操作的事務完整性
editor.commit();
}
namecontent = mShared.getString("name", "數據庫里沒有存儲姓名");
agecontent = mShared.getInt("age", 0);
String reading = "姓名:" + namecontent + "\n年齡:" + agecontent;
return reading;
}
/** 開始清除SharedPreferences中保存的內容 * */
Editor editor = mShared.edit();
editor.remove("name");
editor.remove("age");
editor.commit();
}
/** 刪除SharedPreferences文件 * */
Filefile = new File("/data/data/cn.csdn.activity" + "/shared_prefs/"
+ SHARED_MAIN_XML + ".xml");
if (file.exists()) {
file.delete();
Toast.makeText( this, "刪除成功", Toast.LENGTH_LONG).show();
}
}
haredPreferences對象與SQLite數據庫相比,免去了創建數據庫,創建表,寫SQL語句等諸多操作,相對而言更加方便,簡潔。但是SharedPreferences也有其自身缺陷,比如其職能存儲boolean,int,float,long和String五種簡單的數據類型,比如其無法進行條件查詢等。所以不論SharedPreferences的數據存儲操作是如何簡單,它也只能是存儲方式的一種補充,而無法完全替代如SQLite數據庫這樣的其他數據存儲方式。
2、 File: 即常說的文件(I/O)存儲方法,常用存儲大數量的數據,但是缺點是更新數據將是一件困難的事情。
下面實現:在本地data文件下使用自己生成的文件處理數據的新建儲存 讀取 刪除
如果說不想把內容存在SharedPreferences中的話,我們可以自己寫一個文件保存須要的數據,在這里我將文件保存在系統中的工程路徑下。
跟上面布局一樣,刪除文件也一樣,清除內容也查不多,下面只是簡單的寫和讀的方法:
寫:
try {
os = this.openFileOutput(SHARED_MAIN_XML, MODE_PRIVATE);
/* 把字符串轉換成字節數組,寫入文件中 */
os.write(nameage.getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
/* 關閉文件輸出流 */
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
String nameage="";
// 打開文件輸入流,
try {
is = this.openFileInput(SHARED_MAIN_XML);
/* 初始化字節數組 */
b = new byte[1024];
/* 從文件輸入流中讀取內容到字節數組中,返回內容長度 */
int length = is.read(b);
/* 把字節數組轉換成字符串 */
nameage= new String(b);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return nameage;
}
很簡單吧!!
3、 SQLite是一種轉為嵌入式設備設計的輕型數據庫,其只有五種數據類型,分別是:
NULL: 空值
INTEGER: 整數
REAL: 浮點數
TEXT: 字符串
BLOB: 大數據
它是一個輕量級的數據庫、非常小 、 移植性好、效率高、可靠
在Android系統中提供了android.database.sqlite包,用於進行SQLite數據庫的增、刪、改、查工作。
創建與刪除數據庫
封裝一個類去繼承SQLiteOpenHelper 在構造函數中傳入數據庫名稱與數據庫版本號,數據庫被創建的時候會調用onCreate(SQLiteDatabase db) 方法,數據庫版本號發生改變的時候會調用onUpgrade(SQLiteDatabase db, int oldVersion, intnewVersion)方法,可以方便的對軟件游戲升級后做出相應處理避免覆蓋安裝數據庫發生改變產生的錯誤。調用SQLiteOpenHelper 的getReadableDatabase()方法去創建數據庫,如果數據庫不存在則創建並且返回SQLiteDatabase對象,如果數據庫存在則不創建只返回SQLiteDatabase對象。調用 deleteDatabase(DATABASE_NAME)方法 傳入數據庫名稱則可刪除數據庫。
http://greatverve.cnblogs.com/archive/2011/12/26/android-sqlite-login.html
下面介紹第二種:另一種添刪改查操作
效果圖:
布局文件很簡單,在此不再給出!!
直接給創建數據庫和表,增刪改查的代碼:
private DatabaseHelper helper;
public UserService(Context context, String name, int version) {
helper = new DatabaseHelper(context, name, version);
}
public UserService(Context context, String name) {
helper = new DatabaseHelper(context, name);
}
public void insert(UserDao user) { // 插入數據
SQLiteDatabase sdb = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("username", user.getUsername());
values.put("password", user.getPassword());
sdb.insert("user", "name", values);
sdb.close();
}
public void delete( int id) { // 刪除數據
SQLiteDatabase sdb = helper.getWritableDatabase();
sdb.delete("user", "id=?", new String[]{String.valueOf(id)});
sdb.close();
}
public void update(UserDao user, int id) { // 更新數據
SQLiteDatabase sdb = helper.getWritableDatabase();
ContentValues values= new ContentValues();
values.put("username", user.getUsername());
values.put("password", user.getPassword());
sdb.update("user", values, "id=?", new String[]{String.valueOf(id)});
sdb.close();
}
public Cursor select() { // 查詢所有數據
SQLiteDatabase sdb = helper.getWritableDatabase();
return sdb.query("user", new String[]{"id as _id","username","password"}, null, null, null, null, null);
}
public UserDao find( int id){ // 按id查詢數據
UserDao user= null;
SQLiteDatabase sdb=helper.getWritableDatabase();
Cursor cursor=sdb.query("user", new String[]{"id","username","password"}, "id=?", new String[]{String.valueOf(id)}, null, null, null);
if(cursor.moveToFirst()){
user= new UserDao();
user.setId(cursor.getInt(0));
user.setUsername(cursor.getString(1));
user.setPassword(cursor.getString(2));
}
cursor.close();
sdb.close();
return user;
}
}
插入數據:通過insert(String table, StringnullColumnHack, ContentValues values)方法插入數據,其中參數含義分別為:
table: 目標表名
nullColumnHack: 指定表中的某列列名。因為在SQLite中,不允許不允許插入所有列均為null的記錄,因此初始值有值為空時,此列需顯式賦予null
values:ContentValues對象,類似於java中的Map。以鍵值對的方式保存數據。
修改數據: update(String table,ContentValues values, String whereClause, String[] whereArgs)方法用於修改數據,其四個參數的具體含義如下:
table: 目標表名
values: 要被修改成為的新值
whereClause:where子句,除去where關鍵字剩下的部分,其中可帶?占位符。如沒有子句,則為null。
whereArgs: 用於替代whereClause參數中?占位符的參數。如不需傳入參數,則為null。
查詢數據:query()方法用SELECT 語句段構建查詢。SELECT 語句內容作為 query() 方法的參數,比如:要查詢的表名,要獲取的字段名,WHERE 條件,包含可選的位置參數,去替代 WHERE 條件中位置參數的值,GROUP BY 條件,HAVING 條件。
除了表名,其他參數可以是 null。所以,以前的代碼段可以可寫成:
String[] columns={"ID","inventory"};
String[] parms={"snicklefritz"};
Cursor result=db.query("widgets",columns, "name=?",parms, null, null, null);
使用游標
不管你如何執行查詢,都會返回一個 Cursor,這是 Android 的 SQLite 數據庫游標,使用游標,你可以:
通過使用 getCount() 方法得到結果集中有多少記錄;
通過 moveToFirst(), moveToNext(), 和 isAfterLast() 方法遍歷所有記錄;
通過 getColumnNames() 得到字段名;
通過 getColumnIndex() 轉換成字段號;
通過 getString(),getInt() 等方法得到給定字段當前記錄的值;
通過 requery() 方法重新執行查詢得到游標;
通過 close() 方法釋放游標資源;
刪除數據:刪除數據也是一件很簡單的事,只需要調用delete方法,傳入參數即可,delete(String table, String whereClause,String[] whereArgs)的參數三個參數具體含義如下:
table: 目標表名
whereClause:where子句,除去where關鍵字剩下的部分,其中可帶?占位符。如沒有子句,則為null。
whereArgs: 用於替代whereClause參數中?占位符的參數。如不需傳入參數,則為null。
4、contentprovider
ContentProvider概念
1、 ContentProvider提供為存儲和獲取數據提供了統一的接口;
2、 使用ContentProvider可以在不同的應用程序之間共享數據
3、 Android為常見的一些數據提供了ContentPrivider(包括音頻,視頻,圖片和通訊錄等等)
ContentProvider使用表的形式來組織數據
Uri
1、 每一個ContentProvider都擁有一個公共的uri,這個uri用於表示這個ContentProvider所提供的數據
2、 Android所提供的ContentProvider都存放在android.provider包當中
Uri代表了要操作的數據,Uri主要包含了兩部分信息:1.需要操作的ContentProvider ,對ContentProvider中的什么數據進行操作,一個Uri由以下幾部分組成:
1.scheme:ContentProvider(內容提供者)的scheme已經由Android所規定為:content://。
2.主機名(或Authority):用於唯一標識這個ContentProvider,外部調用者可以根據這個標識來找到它。
3.路徑(path):可以用來表示我們要操作的數據,路徑的構建應根據業務而定,如下:
要操作contact表中id為10的記錄,可以構建這樣的路徑:/contact/10
要操作contact表中id為10的記錄的name字段, contact/10/name
要操作contact表中的所有記錄,可以構建這樣的路徑:/contact
要操作的數據不一定來自數據庫,也可以是文件等他存儲方式,如下:
要操作xml文件中contact節點下的name節點,可以構建這樣的路徑:/contact/name
如果要把一個字符串轉換成Uri,可以使用Uri類中的parse()方法,如下:
Uriuri =Uri.parse("content://com.changcheng.provider.contactprovider/contact")
ContentProvider所提供的函數:
1、 query():查詢
2、 insert():插入
3、 update():更新
4、 delete():刪除
5、 getType():得到數據類型
6、 onCreate():創建時的回調函數
實現ContentProvider的過程
1、 定義一個CONTENT_URI常量
2、 定義一個類,繼承ContentProvider
3、 實現query,insert,update,delete,getType,onCreate方法
4、 在AndroidManifest.xml當中進行聲明
下面是實現代碼:
首先創建繼承contentprovider的類UserContentProvider .java
private DatabaseHelper helper;
private SQLiteDatabase db;
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final int USERS = 1;
private static final int USER = 2;
static{
matcher.addURI("cn.csdn.activity.providers.userprovider", "user", USERS);
matcher.addURI("cn.csdn.activity.providers.userprovider", "user/#", USER);
}
public int delete(Uri uri, String selection, String[]selectionArgs) {
db=helper.getWritableDatabase();
int num=0;
switch(matcher.match(uri)){
case USERS:
num=db.delete("user", selection, selectionArgs);
break;
case USER:
long id=ContentUris.parseId(uri);
String where="id="+id;
if(selection!= null&&!"".equals(selection)){
where=where+" and"+selection;
}
num=db.delete("user", where, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown Uri:"+ uri);
}
return num;
}
public String getType(Uri uri) {
switch(matcher.match(uri)){
case USERS:
return "vnd.android.cursor.dir/person";
case USER:
return "vnd.android.cursor.item/person";
default:
throw new IllegalArgumentException("Unknown Uri:"+ uri);
}
}
public Uri insert(Uri uri, ContentValues values) {
db=helper.getWritableDatabase();
long rowid;
switch(matcher.match(uri)){
case USERS: // 向表中添加新紀錄並返回其行號
rowid=db.insert("user", "id", values);
return ContentUris.withAppendedId(uri, rowid);
default:
throw new IllegalArgumentException("Unknow Uri:" + uri);
}
}
public boolean onCreate() {
helper= new DatabaseHelper( this.getContext(),"users.db");
return true;
}
public Cursor query(Uri uri, String[] projection, Stringselection,
String[] selectionArgs, String sortOrder) {
db = helper.getReadableDatabase();
switch(matcher.match(uri)){
case USERS:
return db.query("user", projection, selection, selectionArgs, null, null, sortOrder);
case USER:
long id=ContentUris.parseId(uri);
String where="id="+id;
if(selection!= null&&!"".equals(selection)){
where=where+" and"+selection;
}
return db.query("user", projection, where, selectionArgs, null, null, sortOrder);
default:
throw new IllegalArgumentException("Unknown Uri:"+ uri);
}
}
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
db=helper.getWritableDatabase();
int num;
switch(matcher.match(uri)){
case USERS:
num=db.update("user", values, selection, selectionArgs);
break;
case USER:
long id=ContentUris.parseId(uri);
String where="id="+id;
if(selection!= null&&!"".equals(selection)){
where=where+" and"+selection;
}
num=db.update("user", values, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknow Uri"+uri);
}
return num;
}
}
配置manifest.xml:
需要在<application></application>中為provider進行注冊!!!!
provider android:authorities="cn.csdn.activity.providers.userprovider"
android:name="UserContentProvider"></provider>
最后寫測試類:
// contentprovider測試
public void testinsert(){ // 插入數據
ContentResolver resolver = this.getContext().getContentResolver();
Uri inserturi=Uri.parse("content://cn.csdn.activity.providers.userprovider/user");
ContentValuesvalues= new ContentValues();
values.put("username", "renhiali");
values.put("password", "123");
Uri uri=resolver.insert(inserturi, values);
Log.i("TAG", uri.toString());
}
public void testdelete(){ // 刪除數據
ContentResolver resolver = this.getContext().getContentResolver();
Uri deleteuri=Uri.parse("content://cn.csdn.activity.providers.userprovider/user/7");
int num=resolver.delete(deleteuri, null, null);
Log.i("TAG", num+"");
}
public void testupdate(){ // 更新數據
ContentResolver resolver = this.getContext().getContentResolver();
Uri uri=Uri.parse("content://cn.csdn.activity.providers.userprovider/user/8");
ContentValuesvalues= new ContentValues();
values.put("username", "123");
resolver.update(uri, values, null, null);
}
public void testquery(){ // 查詢數據
ContentResolver resolver = this.getContext().getContentResolver();
Uri uri=Uri.parse("content://cn.csdn.activity.providers.userprovider/user/4");
Cursor cursor=resolver.query(uri, null, null, null, null);
cursor.moveToFirst();
Log.i("TAG",cursor.getString(1));
cursor.close();
}