Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 安卓速記--數據存儲方式

安卓速記--數據存儲方式

編輯:關於Android編程

Android提供以下四種存儲方式:

SharePreference

SQLite

File

ContentProvider

如果要實現數據共享,正確的方式是使用ContentProvider

 

\

 

 

SharedPreference

  • “用戶的偏好設置”通常用來存儲程序的一些配置信息。
  • 其存儲在“data/data/程序包名/shared_prefs目錄下。
  • 使用鍵-值的形式來存儲數據;我們只需要調用SharedPreferences的getXxx(name), 就可以根據鍵獲得對應的值!
  • SharedPreference本身只能獲取數據,存儲和修改要通過Editor對象來實現。

代碼速記:

存儲數據

SharedPreferencessp =context.getSharedPreferences("CITY", MODE_PRIVATE); //獲取對象
Editoreditor=sp.edit();
editor.putString("CityName",City.getCity().getCityName());//存儲數據
editor.commit();//將數據提交 

 

讀取數據

//定義一個讀取SP文件的方法

public Map read() {
Map data =new HashMap();
SharedPreferences sp =mContext.getSharedPreferences("mysp", Context.MODE_PRIVATE);
data.put("username", sp.getString("username","")); //獲取數據;
data.put("passwd", sp.getString("passwd",""));
return data;
}

 

 

SharedPreference工具類:

SPUtils.java

 

 

 

package com.jay.sharedpreferencedemo3;

import android.content.Context;
import android.content.SharedPreferences;

import java.util.Map;

/**
 * Created by Jay on 2015/9/2 0002.
 */
public class SPUtils {
    /**
     * 保存在手機裡的SP文件名
     */
    public static final String FILE_NAME = "my_sp";

    /**
     * 保存數據
     */
    public static void put(Context context, String key, Object obj) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        if (obj instanceof Boolean) {
            editor.putBoolean(key, (Boolean) obj);
        } else if (obj instanceof Float) {
            editor.putFloat(key, (Float) obj);
        } else if (obj instanceof Integer) {
            editor.putInt(key, (Integer) obj);
        } else if (obj instanceof Long) {
            editor.putLong(key, (Long) obj);
        } else {
            editor.putString(key, (String) obj);
        }
        editor.commit();
    }


    /**
     * 獲取指定數據
     */
    public static Object get(Context context, String key, Object defaultObj) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        if (defaultObj instanceof Boolean) {
            return sp.getBoolean(key, (Boolean) defaultObj);
        } else if (defaultObj instanceof Float) {
            return sp.getFloat(key, (Float) defaultObj);
        } else if (defaultObj instanceof Integer) {
            return sp.getInt(key, (Integer) defaultObj);
        } else if (defaultObj instanceof Long) {
            return sp.getLong(key, (Long) defaultObj);
        } else if (defaultObj instanceof String) {
            return sp.getString(key, (String) defaultObj);
        }
        return null;
    }

    /**
     * 刪除指定數據
     */
    public static void remove(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.remove(key);
        editor.commit();
    }


    /**
     * 返回所有鍵值對
     */
    public static Map getAll(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        Map map = sp.getAll();
        return map;
    }

    /**
     * 刪除所有數據
     */
    public static void clear(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.clear();
        editor.commit();
    }

    /**
     * 檢查key對應的數據是否存在
     */
    public static boolean contains(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        return sp.contains(key);
    }

}

 

SQLite

 

  • SQLite是一個輕量級關系型數據庫,只有NULL、INTEGER、REAL(浮點數)、TEXT(字符串)和BLOB(大數據)五種類型,不存在BOOLEAN和DATE類型。
  • SQLiteOpenHelper:抽象類,我們通過繼承該類,然後重寫數據庫創建以及更新的方法, 我們還可以通過該類的對象獲得數據庫實例,或者關閉數據庫!
  • SQLiteDatabase:數據庫訪問類:我們可以通過該類的對象來對數據庫做一些增刪改查的操作
  • Cursor:游標,有點類似於JDBC裡的resultset,結果集!可以簡單理解為指向數據庫中某 一個記錄的指針!

 

代碼速記:

(1).創建數據庫

 

public class MyDBOpenHelper extends SQLiteOpenHelper {
    public MyDBOpenHelper(Contextcontext, String name, CursorFactory factory,
            int version){super(context, "my.db", null, 1); }
    @Override
    //數據庫第一次創建時被調用
    public voidonCreate(SQLiteDatabase db) {
        db.execSQL("CREATETABLE person(personid INTEGER PRIMARY KEY AUTOINCREMENT,nameVARCHAR(20))");
       
    }
    //軟件版本號發生改變時調用
    @Override
    public voidonUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("ALTERTABLE person ADD phone VARCHAR(12) NULL");
    }
}

 

(2).插入數據:

dbOpenHelper.getWritableDatabase()

 

public voidsave(Person p)
{
    SQLiteDatabase db =dbOpenHelper.getWritableDatabase();
    db.execSQL("INSERT INTOperson(name,phone) values(?,?)",new String[]{p.getName(),p.getPhone()});
}

 

3.刪除數據:同上

db.execSQL("DELETE FROM person WHEREpersonid = ?",new String[]{id});

4.修改數據:同上

db.execSQL("UPDATE person SET name =?,phone = ? WHERE personid = ?",newString[]{p.getName(),p.getPhone(),p.getId()});

5.查詢數據:

dbOpenHelper.getReadableDatabase()

 

public Personfind(Integer id)
{
    SQLiteDatabase db =dbOpenHelper.getReadableDatabase();
    Cursor cursor =  db.rawQuery("SELECT * FROM person WHEREpersonid = ?",new String[]{id.toString()});
    //存在數據才返回true
    if(cursor.moveToFirst())
    {
        int personid =cursor.getInt(cursor.getColumnIndex("personid"));
        String name =cursor.getString(cursor.getColumnIndex("name"));
        String phone =cursor.getString(cursor.getColumnIndex("phone"));
        return new Person(personid,name,phone);
    }
    cursor.close();
    return null;
}

 

6.數據分頁:

dbOpenHelper.getReadableDatabase()

 

publicList getScrollData(int offset,int maxResult)
{
    List person = newArrayList();
    SQLiteDatabase db =dbOpenHelper.getReadableDatabase();
    Cursor cursor =  db.rawQuery("SELECT * FROM person ORDERBY personid ASC LIMIT= ?,?",
        newString[]{String.valueOf(offset),String.valueOf(maxResult)});
    while(cursor.moveToNext())
    {
        int personid =cursor.getInt(cursor.getColumnIndex("personid"));
        String name =cursor.getString(cursor.getColumnIndex("name"));
        String phone =cursor.getString(cursor.getColumnIndex("phone"));
        person.add(newPerson(personid,name,phone)) ;
    }
    cursor.close();
    return person;
}


 

7.查詢記錄數:

dbOpenHelper.getReadableDatabase()

 

public longgetCount()
{
    SQLiteDatabase db =dbOpenHelper.getReadableDatabase();
    Cursor cursor =  db.rawQuery("SELECT COUNT (*) FROMperson",null);
    cursor.moveToFirst();
    long result = cursor.getLong(0);
    cursor.close();
    return result;     
}  

 

PS:除了上面獲取條數的方法外還可以使用cursor.getCount()方法獲得數據的條數, 但是SQL語句要改改!比如SELECT * FROMperson;

 

File

文件存儲讀寫

openFileOutput(filename,mode) 往文件寫數據

openFileIntput(filename) 讀取文件中的信息到程序

getDir(name,mode) 在app的data目錄下獲取或創建name對應的子目錄

getFileDir() 獲取app的data目錄的file目錄的絕對路徑

String[]fileList() 返回app的data目錄下的全部文件

deleteFile(filename) 刪除app的data目錄下的指定文件

 

ContentProvider

ContentProvider相對於其它的方式比較復雜。它能夠實現跨應用之間的數據操作。利用ContentResolver對象的delete、update、insert、query等方法去操ContentProvider的對象,讓ContentProvider對象的方法去對數據操作。實現方式為:

 

 

  •  
在A程序中定義一個ContentProvider,重載其增刪查改等方法;

 

  •  
  • 在A程序中的AndroidManifest.xml中注冊ContentProvider;
  • 在B程序中通過ContentResolver和Uri來獲取ContentProvider的數據,同樣利用Resolver的增刪查改方法來獲得和處理數據。

在A程序定義一個Provider

新建一個類,繼承ContentProvider,並重載其delete()、insert()、query()、update()、getType()、onCreate()方法。譬如下面的例子,重載其onCreate和query方法 注:從5.0開始,默認短信應用外的軟件不能以寫入短信數據庫的形式發短信!
public class MyProvider extends ContentProvider {

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public String getType(Uri uri) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean onCreate() {
        // 新建個數據庫並插入一條數據
        SQLiteDatabase db=this.getContext().openOrCreateDatabase("test_db2.db", Context.MODE_PRIVATE, null);
        db.execSQL("CREATE TABLE t_user (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL)");
        ContentValues values=new ContentValues();
        values.put("name", "liangjh2");
        db.insert("t_user", "id", values);
        db.close();
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        // 獲取數據
        SQLiteDatabase db=this.getContext().openOrCreateDatabase("test_db2.db", Context.MODE_PRIVATE, null);
        Cursor c = db.query("t_user", null, null, null, null, null, null);
        db.close();
        return c;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO Auto-generated method stub
        return 0;
    }

}

  注冊ContentProvider 在AndroidManifest.xml中聲明ContentProvider,authorities屬性定義了ContentProvider的Uri標識。關於Uri標識屬另一個范疇,自行查詢。provider標識要放在裡面。如果遇到了"Permission Denial: opening provide..."的錯誤,可以試試在節點加“android:exported="true"”。

    ...
    

 

在B程序獲取數據 用Context獲取到當前的ContentResolver,根據Uri地址和ContentResolver的query方法獲取A程序的數據。Uri地址和A程序中AndroidManifest.xml定義的autorities要一致。當然,同類可以進行其它的操作。
Context ctx=MainActivity.this;
ContentResolver resolver =ctx.getContentResolver();
Uri uri=Uri.parse("content://com.example.androidtestdemo");
Cursor c = resolver.query(uri, null, null, null, null);
c.moveToFirst();
while(!c.isAfterLast()){
    for(int i=0,j=c.getColumnCount();i

讀取收件箱信息:

private void getMsgs(){
    Uri uri = Uri.parse("content://sms/");
    ContentResolver resolver = getContentResolver();
    //獲取的是哪些列的信息
    Cursor cursor = resolver.query(uri, new String[]{"address","date","type","body"}, null, null, null);
    while(cursor.moveToNext())
    {
        String address = cursor.getString(0);
        String date = cursor.getString(1);
        String type = cursor.getString(2);
        String body = cursor.getString(3);
        System.out.println("地址:" + address);
        System.out.println("時間:" + date);
        System.out.println("類型:" + type);
        System.out.println("內容:" + body);
        System.out.println("======================");
    }
    cursor.close();
}

往AndroidManifest.xml加入讀取收件箱的權限:

往收件箱裡插入一條信息

private void insertMsg() {
    ContentResolver resolver = getContentResolver();
    Uri uri = Uri.parse("content://sms/");
    ContentValues conValues = new ContentValues();
    conValues.put("address", "123456789");
    conValues.put("type", 1);
    conValues.put("date", System.currentTimeMillis());
    conValues.put("body", "no zuo no die why you try!");
    resolver.insert(uri, conValues);
    Log.e("HeHe", "短信插入完畢~");
}

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved