Android四種數據存儲方式

存儲方式java

Android提供如下四種存儲方式:mysql

  • SharePreferenceandroid

  • SQLitesql

  • File數據庫

  • ContentProvider安全

Android系統中數據基本都是私有的,通常存放在「data/data/程序包名」目錄下。若是要實現數據共享,正確的方式是使用ContentProvider。app

 


SharedPreferenceide

SharedPreference是一種輕型的數據存儲方式,其實是基於XML文件存儲的「key-value」鍵值對數據。一般用來存儲程序的一些配置信息。其存儲在「data/data/程序包名/shared_prefs目錄下。大數據

SharedPreference自己只能獲取數據,不支持存儲和修改。存儲和修改要經過Editor對象來實現。this

 

修改和存儲數據

  • 根據Context的getSharedPrerences(key, [模式])方法獲取SharedPreference對象;

  • 利用SharedPreference的editor()方法獲取Editor對象;

  • 經過Editor的putXXX()方法,將鍵值對存儲數據;

  • 經過Editor的commit()方法將數據提交到SharedPreference內。

綜合例子:

    //設置單例裏面的數值,而後再將數值寫入到SharedPreference裏

複製代碼

    private String setCityName(String _cityName){
        City.getCity().setCityName(_cityName);
        
        Context ctx =MainActivity.this;
        SharedPreferences sp =ctx.getSharedPreferences("CITY", MODE_PRIVATE);
        Editor editor=sp.edit();
        editor.putString("CityName", City.getCity().getCityName());
        editor.commit();        
        return City.getCity().getCityName();
    }

複製代碼

 

獲取數據

  • 一樣根據Context對象獲取SharedPreference對象;

  • 直接使用SharedPreference的getXXX(key)方法獲取數據。

 

綜合例子:

    //從單例裏面找,若是不存在則在SharedPreferences裏面讀取

複製代碼

    private String getCityName(){
        String cityName = City.getCity().getCityName();        if(cityName==null ||cityName==""){
            Context ctx =MainActivity.this;
            SharedPreferences sp =ctx.getSharedPreferences("CITY", MODE_PRIVATE);
            City.getCity().setCityName(sp.getString("CityName", "廣州"));
        }        return City.getCity().getCityName();
    }

複製代碼

注意

  • getSharedPrerences(key, [模式])方法中,第一個參數其實對應到XML的文件名,相同key的數據會保存到同一個文件下。

  • 使用SharedPreference的getXXX(key)方法獲取數據的時候,若是key不存在的活,不會出現報錯,會返回none。建議使用getXXX()的時候指定默認值。

 


SQLite

SQLite是一個輕量級關係型數據庫,既然是關係型數據庫,那操做起來其實跟mysql、sql server差很少的。

須要注意的一點是,SQLite只有NULL、INTEGER、REAL(浮點數)、TEXT(字符串)和BLOB(大數據)五種類型,不存在BOOLEAN和DATE類型。

 

建立數據庫

        經過openOrCreateDatabase(String path, SQLiteDatabase.CursorFactory factory)方法建立,若是庫已建立,則打開數據庫。

SQLiteDatabase db =this.openOrCreateDatabase("test_db.db", Context.MODE_PRIVATE, null);

建立表

        SQLiteDatabase沒有提供建立表的方法,因此要靠execSQL()方法來實現。看名字也知道execSQL()用於直接執行sql的。

String sql="create table t_user (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL,password TEXT NOT NULL)";
db.execSQL(sql);

 

        使用SQLiteDatabase的insert(String table, String nullColumnHack, ContentValues values)方法插入數據。ContentValues 類,相似於java中的Map,以鍵值對的方式保存數據。

ContentValues values=new ContentValues();
values.put("name", "liangjh");
values.put("password", "123456");
db.insert("t_user", "id", values);

 

        刪除數據就比較直接了。使用SQLiteDatabase的delete(String table, String whereClause, String[] whereArgs)實現。若是不想把參數寫在whereArgs裏面,能夠直接把條件寫在whereClause裏面。

// 方式1 直接將條件寫入到條件裏面(我的以爲容易被注入,但其實數據都在客戶端,沒啥安全性可言)db.delete("t_user", "id=1", null);// 方式2 條件分開寫,感受比較安全db.delete("t_user", "name=? and password =?", new String[]{"weiyg","112233"});

 

        查詢有2個方法,query()和rawQuery()兩個方法,區別在於query()是將sql裏面的各參數提取出query()對應的參數中。可參考下面例子。

複製代碼

// 使用rawQuery// Cursor c = db.rawQuery("select * from t_user", null);// db.rawQuery("select * from t_user where id=1", null);// db.rawQuery("select * from t_user where id=?", new String[]{"1"}); 
// 使用query()Cursor c = db.query("t_user", new String[]{"id","name"}, "name=?", new String[]{"weiyg"}, null, null, null);
c.moveToFirst();while(!c.isAfterLast()){
    String msg="";    for(int i=0,j=c.getColumnCount();i<j;i++){
        msg+="--"+c.getString(i);
    }
    Log.v("SQLite", "data:"+msg);
    c.moveToNext();
}

複製代碼

 

        使用SQLiteDatabase 的update(String table, ContentValues values, String whereClause, String[] whereArgs)能夠修改數據。whereClause和whereArgs用於設置其條件。ContentValues對象爲數據。

複製代碼

ContentValues values=new ContentValues();
values.put("password", "111111");// 方式1 條件寫在字符串內db.update("t_user", values, "id=1", null);// 方式2 條件和字符串分開db.update("t_user", values, "name=? or password=?",new String[]{"weiyg","123456"});

複製代碼

 

其它

不管什麼時候,打開的數據庫,記得關閉。

db.close()

另外使用beginTransaction()和endTransaction()能夠設置事務。

 


File

        文件儲存方式,好久之前講過,這裏不說明。

 


 

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方法。

複製代碼

 1 public class MyProvider extends ContentProvider { 2  3     @Override 4     public int delete(Uri uri, String selection, String[] selectionArgs) { 5         // TODO Auto-generated method stub 6         return 0; 7     } 8  9     @Override10     public String getType(Uri uri) {11         // TODO Auto-generated method stub12         return null;13     }14 15     @Override16     public Uri insert(Uri uri, ContentValues values) {17         // TODO Auto-generated method stub18         return null;19     }20 21     @Override22     public boolean onCreate() {23         // 新建個數據庫並插入一條數據24         SQLiteDatabase db=this.getContext().openOrCreateDatabase("test_db2.db", Context.MODE_PRIVATE, null);25         db.execSQL("CREATE TABLE t_user (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL)");26         ContentValues values=new ContentValues();27         values.put("name", "liangjh2");28         db.insert("t_user", "id", values);29         db.close();30         return false;31     }32 33     @Override34     public Cursor query(Uri uri, String[] projection, String selection,35             String[] selectionArgs, String sortOrder) {36         // 獲取數據37         SQLiteDatabase db=this.getContext().openOrCreateDatabase("test_db2.db", Context.MODE_PRIVATE, null);38         Cursor c = db.query("t_user", null, null, null, null, null, null);39         db.close();40         return c;41     }42 43     @Override44     public int update(Uri uri, ContentValues values, String selection,45             String[] selectionArgs) {46         // TODO Auto-generated method stub47         return 0;48     }49 50 }

複製代碼

 

 

註冊ContentProvider

在AndroidManifest.xml中聲明ContentProvider,authorities 屬性定義了ContentProvider的Uri標識。關於Uri標識屬另外一個範疇,自行查詢。provider標識要放 在<application></application>裏面。若是遇到了"Permission Denial: opening provide..."的錯誤,能夠試試在節點加「android:exported="true"」。

<application ...>
    ...    <provider android:name=".MyProvider" android:authorities="com.example.androidtestdemo" android:exported="true"/></application>

 

在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<j;i++){
        Log.v("Android2",""+c.getString(i));
    }
    c.moveToNext();
}

複製代碼

相關文章
相關標籤/搜索