ContentProvider!

ContentProvider是Android四大組件之一。它主要的作用是:實(shí)現(xiàn)各個(gè)應(yīng)用程序之間的(跨應(yīng)用)數(shù)據(jù)共享,比如聯(lián)系人應(yīng)用中就使用了ContentProvider,你在自己的應(yīng)用中可以讀取和修改聯(lián)系人的數(shù)據(jù),不過需要獲得相應(yīng)的權(quán)限。
但是ContentProvider也只是起到中間人的作用,真正實(shí)現(xiàn)應(yīng)用間數(shù)據(jù)傳輸?shù)挠肧QLite。
和ContentProvider緊密祥光的就是URI!
Uri是統(tǒng)一標(biāo)識符,代表要操作的數(shù)據(jù),標(biāo)識每一個(gè)ContentProvider,當(dāng)需要的時(shí)候就通過Uri來查找對應(yīng)想要的ContentProvider。從而獲取和修改等其他操作。
Android中的Uri的格式也是一下的形式,主要分為三個(gè)部分:

   A 部分:表示是一個(gè)Android內(nèi)容URI,說明由ContentProvider控制數(shù)據(jù),該部分是固定形式,不可更改的。
  ?B 部分:是URI的授權(quán)部分,是唯一標(biāo)識符,用來定位ContentProvider。
     格式一般是自定義ContentProvider類的完全限定名稱,注冊時(shí)需要用到,
     如:com.alexzhou.provider.NoteProvider
  ?C 部分和D部分:是每個(gè)ContentProvider內(nèi)部的路徑部分,C和D部分稱為路徑片段,C部分指向一個(gè)對象集合,
     一般用表的名字,如:/notes表示一個(gè)筆記集合;D部分指向特定的記錄,如:/notes/1表示id為1的筆記,
     如果沒有指定D部分,則返回全部記錄。
Paste_Image.png

ContentProvider可以理解為一個(gè)Android應(yīng)用對外開放的接口,只要是符合它所定義的Uri格式的請求,均可以正常訪問執(zhí)行操作。
其他的Android應(yīng)用可以使用ContentResolver對象通過與ContentProvider同名的方法請求執(zhí)行,被執(zhí)行的就是ContentProvider中的同名方法。
所以ContentProvider很多對外可以訪問的方法,在ContentResolver中均有同名的方法,是一一對應(yīng)的!

Paste_Image.png

ContentProvider必須要實(shí)現(xiàn)的幾個(gè)方法:
1、onCreate():初始化提供者。

@Override
    public boolean onCreate() {
        // TODO Auto-generated method stub
        Log.e(TAG, "onCreate");
        helper = new MySqliteHelper(getContext());
        matcher = new UriMatcher(UriMatcher.NO_MATCH);
        matcher.addURI(authority, tableName, STUDENT);
        matcher.addURI(authority, teachName, TEACHER);
        return true;
    }```
2、insert(Uri, ContentValues):插入一條數(shù)據(jù)。
3、query(Uri, String[], String, String[], String):查詢數(shù)據(jù),返回一個(gè)數(shù)據(jù)Cursor對象。(根據(jù)括號里的參數(shù)查詢數(shù)據(jù),后面類型的填null代表所有的數(shù)據(jù)都要查詢)

@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
int code = matcher.match(uri);
db = helper.getReadableDatabase();
switch (code) {
case TEACHER:
Log.e(TAG, "teacher_query");
Cursor teachCursor = db.query(teachName, projection, selection,
selectionArgs, null, null, null);
return teachCursor;

    case STUDENT:
        Log.e(TAG, "teacher_query");
        Cursor cursor = db.query(tableName, projection, selection,
                selectionArgs, null, null, null);
        return cursor;
    }
    return null;
}```

4、delete(Uri, String, String[]):根據(jù)條件刪除數(shù)據(jù)。

@Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // TODO Auto-generated method stub
        
        int code=matcher.match(uri);
        db = helper.getReadableDatabase();
        switch(code){
        case TEACHER:
            Log.e(TAG, "teacher_delete");
            db.delete(teachName, selection, selectionArgs);
            break;
            
        case STUDENT:
            Log.e(TAG, "student_delete");
            db.delete(tableName, selection, selectionArgs);
            break;
        }
        return 0;
    }```

在ContentProvider的增刪改查操作中,均會傳遞一個(gè)Uri對象,通過這個(gè)對象來匹配對應(yīng)的請求。那么如何確定一個(gè)Uri執(zhí)行哪項(xiàng)操作呢?
需要用到一個(gè)UriMatcher對象,這個(gè)對象用來幫助內(nèi)容提供者匹配Uri。它所提供的方法非常簡單,僅有兩個(gè):
void addURI(String authority,String path,int code):添加一個(gè)Uri匹配項(xiàng),authority為AndroidManifest.xml中注冊的ContentProvider中的authority屬性;path為一個(gè)路徑,可以設(shè)置通配符,#表示任意數(shù)字,*表示任意字符;code為自定義的一個(gè)Uri代碼。

int match(Uri uri):匹配傳遞的Uri,返回addURI()傳遞的code參數(shù)。
     在創(chuàng)建好一個(gè)ContentProvider之后,還需要在AndroidManifest.xml文件中對ContentProvider進(jìn)行配置,使用一個(gè)<provider.../>節(jié)點(diǎn),一般只需要設(shè)置兩個(gè)屬性即可訪問,一些額外的屬性就是為了設(shè)置訪問權(quán)限而存在的,后面會詳細(xì)講解:
android:name:provider的響應(yīng)類。
android:authorities:Provider的唯一標(biāo)識,用于Uri匹配,一般為ContentProvider類的全名。
        ContentProvider也是四大組件之一所以需要在Manifest中注冊;

在ContentProvider之前要?jiǎng)?chuàng)建一個(gè)類(MySqliteHelper)來繼承SQLiteOpenHelper這個(gè)類,其中要調(diào)用一個(gè)構(gòu)造方法和兩個(gè)方法(一個(gè)創(chuàng)建的方法,一個(gè)更新版本的方法)。在創(chuàng)建的方法里要?jiǎng)?chuàng)建一個(gè)表格要用用Sql語句來完成

@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("CREATE TABLE Student(id integer primary key autoincrement,name varchar(20),age varchar(10))");
db.execSQL("CREATE TABLE Teacher(id integer primary key autoincrement,tname varchar(20),tage varchar(10))");
}```

都寫好了之后,就在另一個(gè)程序內(nèi)加上點(diǎn)擊的事件---增刪改查的點(diǎn)擊方法,來操作ContentProvider內(nèi)寫好的對應(yīng)的增刪改查

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch(v.getId()){
        case R.id.but_insert:
            ContentValues values=new ContentValues();
            values.put("tname", "老師");
            values.put("tage", "23");
            ContentValues values1=new ContentValues();
            values1.put("tname", "老師師");
            values1.put("tage", "123");
            resolver.insert(teachUri, values);
            resolver.insert(teachUri, values1);
            break;
        case R.id.but_update:
            ContentValues updateValues=new ContentValues();
            updateValues.put("tname", "李四");
            updateValues.put("tage", "32");
            resolver.update(teachUri, updateValues, "tname=?", new String[]{"老師"});
            break;
        case R.id.but_query:
            List<String> list=new ArrayList<String>();
            Cursor cursor=resolver.query(teachUri, null, null, null, null);
            while(cursor.moveToNext()){
                int nameIndex=cursor.getColumnIndex("tname");
                int ageIndex=cursor.getColumnIndex("tage");
                String nameStr=cursor.getString(nameIndex);
                String ageStr=cursor.getString(ageIndex);
                list.add(nameStr+ageStr);
            }
            ArrayAdapter adapter=new ArrayAdapter(this, android.R.layout.simple_list_item_1, list);
            lv.setAdapter(adapter);
            break;
        case R.id.but_delete:
            resolver.delete(teachUri, "tname=?", new String[]{"李四"});
            break;
        }
    }```
準(zhǔn)備工作就是生命一個(gè)Uri、ContentResolver。

String uriStr="content://com.example.contentprovider.MyProvider/Student";
uri=Uri.parse(uriStr);

將一個(gè)字符串轉(zhuǎn)化成一個(gè)Uri格式的類型

resolver=getContentResolver();

獲取resolver的實(shí)例
通過上述操作可以實(shí)現(xiàn)ContentProvider應(yīng)用之間的相互操作!

-----------------------------------------------------------------------------
相互學(xué)習(xí),共同進(jìn)步!
------------------------------------------------------------------------------













最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,179評論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,628評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,642評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,444評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,948評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,185評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,717評論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,794評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,418評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,414評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,750評論 2 370

推薦閱讀更多精彩內(nèi)容