亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

深入Understanding Android ContentProvider詳解

2020-04-11 12:22:40
字體:
來源:轉載
供稿:網友
1. 什么是ContentProvider
也即內容提供者,是對所有數據訪問的一層抽象,為數據訪問提供了統一的接口。它有以下優點:
a. 對數據的抽象,為所有的組件提供統一的訪問數據的方式,從而讓組件不必關心具體數據的呈現形式(文件or數據庫)。數據,也可以只關心自身的管理,而不用去管使用者的訪問問題。這樣就達到了很好的封裝。
b. 接口更加方便,更加方便的讓組件之間傳送數據
ContentProvider的訪問標識為Uri,通過統一的ContentResolver進行訪問,而ContentResolver和Uri跟Application的上下文Context以及組件之間的信息傳送工具Intent都是無縫接合,這就讓組件之間進行數據共享和數據傳遞更加的方便和快捷。
所以,ContentProvider的最大好處在于它可以在不同組件之間方便的共享。所以,如果你的應用里面用到的數據需要在不同的組件之間共享,那么實現一個ContentProvider無疑是最佳方案。
2. 實現方式
ContentProvider的實現方式非常簡單,只需要根據需求實現一些接口即可,比如:query, insert, delete, update, openFile等。但是具體的數據的呈現形式則是根據不同的目的進行自由選擇,比如對于結構化數據,選擇SQLiteDatabase可能是比較好的方案,大量的字節流可能文件是首選等等。
需要注意一點的是,雖然Android中百分之九十的ContentProvider內部都是用SQLiteDatabase來存儲結構化數據,但這并不意味著ContentProvider只能從SQLiteDatabase來管理數據。ContentProvider定義了一些接口,你只需要按照需要返回正確的數據即可,具體 的實現方式則由你自由選擇。
比如,Contacts的ContentProvider能提供以vCard的方式輸出,也就是說當讀取一個vCard的uri時,這個流是一個vCard形式的文件流,實現起來的思路就是這樣:
復制代碼 代碼如下:

Cursor query(Uri, ....) {
   if (uri is for vCard) {
       query the Contact's infomation
       create a cursor with two columns name and size
       put contact's name into cursor
       sum all Contact's field  and get size
       put that size into cursor
       return the cursor
   }
}

這樣通過Query就能得到這個vCard的相關信息文件名字和大小,再通過openInputStream就可以讀取這個vCard文件流,但是實際上ContentProvider是沒有vCard形式的數據,也沒有一個vCard的文件,它只是在openFile的時候,識別出vCard的uri,把Contact數據轉化成vCard形式寫入輸出流中:
復制代碼 代碼如下:

ParcelFileDescriptor openFile(Uri...) {
    if (uri is for vcard) {
       generate vcard with VCardComposer
       write to output stream
    }
}

3. 其他替代方案
ContentProvider不是必須的,每個應用必然用到數據,但是可以選擇用創建一個ContentProvider來管理,也可以直接使用文件或數據庫,如下面的例子:
復制代碼 代碼如下:

package com.android.effective;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.os.Bundle;
import android.util.Log;
public class SQLiteDatabaseDemo extends Activity {
    private static final String TAG = "SQLiteDatabaseDemo";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MyDatabase db = new MyDatabase(this);

        int id = db.setName("Michael Jordan");
        Log.e(TAG, "id of " + id + " is " + db.getName(id));
    }

    private class MyDatabase {
        private static final String name = "demo.db";
        private static final String table = "demo";
        private final String[] projection = new String[] {"_id", "name" };
        private MyDatabaseHelper helper;

        public MyDatabase(Context context) {
            helper = new MyDatabaseHelper(context, name, null, 1);
        }

        public String getName(int id) {
            final Cursor c = helper.getReadableDatabase().query("demo", projection, "_id=" + id,
                    null, null, null, null);
            if (c == null || !c.moveToFirst()) {
                return null;
            }
            return c.getString(1);
        }

        public int setName(String name) {
            ContentValues cv = new ContentValues();
            cv.put("name", name);
            return (int) helper.getWritableDatabase().insert(table, "name", cv);
        }
    }

    private class MyDatabaseHelper extends SQLiteOpenHelper {
        public MyDatabaseHelper(Context context, String name,
                CursorFactory factory, int version) {
            super(context, name, factory, version);
        }
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE demo (_id INTEGER PRIMARY KEY, name TEXT);");
        }
        @Override
        public void onUpgrade(SQLiteDatabase db, int old, int newver) {

        }
    }
}

這個例子中就沒有使用ContentProvider而是讓Activity直接操作SQLiteDatabase來實現數據的管理,或者不用數據庫而直接使用文件進行管理數據。
這種方式實現起來可能更簡單,對于需求不大,數據量不大,且只有單一組件使用的情況下,完全可以用這種方式。但是它的缺點也很明顯,就是在組件之間傳遞會十分麻煩,甚至不能夠在組件之間共享。為了共享,就要把數據層進行抽象,使其獨立于任何一個Activity,以滿足不同的組件對數據進行讀寫,但是這樣一來跟實現一個ContentProvider就沒有區別了,還不如實現一個ContentProvider來的方便。
所以,規則就是如果某些數據只在一個Activity中使用,那么沒有必要創建ContentProvider,直接使用文件或直接操作Database就可以達到目的。但是如果需要跟其他的組件進行共享和傳遞數據,就必須使用ContentProvider。
另外,有了ContentProvider也可以方便跟其他應用進行交互,把數據傳遞給其他應用的組件。
在使用SQLiteOpenHelper一定要注意線程同步問題,保證每一個SQLiteDatabase的方法(如execSQL)的線程安全性,否則可能會引起十分罕見的異常。曾遇到一個SQLiteStatement報出的NPE(NullPointerException),就是由于有多個線程在操作同一個SQLiteOpenHelper,而且沒有同步。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲精品视频在线播放| 亚洲欧美国产一区二区三区| 青青青国产精品一区二区| 国产精品久久久亚洲| 中文字幕精品国产| 欧美成人网在线| 亚洲视频一区二区三区| 日韩中文字幕在线| 国产精品久久久久久久天堂| 欧美二区在线播放| 欧美日韩在线观看视频小说| 久久人人爽人人爽人人片av高请| 伦伦影院午夜日韩欧美限制| 亚洲精品美女在线观看播放| 国产免费一区视频观看免费| 中文在线不卡视频| 国产亚洲精品91在线| 国产精品爽爽爽| 日韩欧美中文字幕在线观看| 成人黄色免费网站在线观看| 国产精品都在这里| 久久精品成人欧美大片古装| 日韩一区二区久久久| 国产午夜精品美女视频明星a级| 久久国产精品久久国产精品| 欧美极度另类性三渗透| 欧美精品videossex性护士| 国产精品久久久久久久久久尿| 中文字幕日韩欧美| 国产剧情久久久久久| 欧美日韩国产中文字幕| 久久香蕉精品香蕉| 欧美在线视频在线播放完整版免费观看| 最新国产成人av网站网址麻豆| 色久欧美在线视频观看| 成人信息集中地欧美| 亚洲二区在线播放视频| 国产精品久久久久久av福利| 成人妇女淫片aaaa视频| 国产精品专区一| 懂色av影视一区二区三区| 国产精品伦子伦免费视频| 国产成人一区二区三区小说| 国产在线拍揄自揄视频不卡99| 久热精品视频在线观看一区| 久久国产精品电影| 欧美成人网在线| 欧美中在线观看| 中文字幕日韩av综合精品| 国产成人精品av| 精品久久久999| 欧美乱大交做爰xxxⅹ性3| 日韩亚洲精品视频| 成人深夜直播免费观看| 国产手机视频精品| 2019中文字幕在线免费观看| 97精品久久久中文字幕免费| 高清欧美性猛交| 91免费福利视频| 综合136福利视频在线| 久久综合伊人77777蜜臀| 日韩欧美国产激情| 亚洲男人天堂手机在线| 亚洲国产成人91精品| 中文字幕日韩精品在线观看| 欧美裸体xxxx极品少妇| 97精品视频在线观看| 日本国产一区二区三区| 国产精品69久久| 国产成人在线一区| 欧美日产国产成人免费图片| 日韩成人xxxx| 国产综合色香蕉精品| 一本色道久久88综合亚洲精品ⅰ| 日韩中文字幕不卡视频| 国产精品久久久久久久久久久久久| 日韩精品视频免费| 蜜臀久久99精品久久久无需会员| 91综合免费在线| 欧美色xxxx| 亚洲性生活视频在线观看| 成人精品视频久久久久| 国产一区二区三区视频免费| 欧美精品在线网站| 亚洲美腿欧美激情另类| 国产成人高清激情视频在线观看| 日韩va亚洲va欧洲va国产| 久久精品男人天堂| 亚洲精选在线观看| 欧美视频不卡中文| 久久九九全国免费精品观看| 欧美有码在线观看| 日韩精品在线看| 日韩中文字幕不卡视频| 在线电影欧美日韩一区二区私密| 亚洲精品一区二三区不卡| 亚洲精品成人久久久| 欧美国产日韩在线| 国内精品美女av在线播放| 91精品国产高清| 欧美激情一二区| 欧美一二三视频| 国产主播精品在线| 欧美在线一区二区三区四| 亚洲黄色在线观看| 久久免费视频网站| 国产精品成人一区二区三区吃奶| 国产欧美在线看| 欧美激情一二三| 91精品国产综合久久香蕉| 日韩一区二区在线视频| 亚洲国产99精品国自产| 免费99精品国产自在在线| 欧美国产日韩二区| 国产日韩欧美91| 成人福利视频网| 国产香蕉97碰碰久久人人| 精品国产户外野外| 久久久久久久久久国产精品| 欧美成人在线免费| 美女久久久久久久久久久| 性欧美视频videos6一9| 亚洲字幕在线观看| 亚洲成人三级在线| 91在线视频精品| 日韩av有码在线| 亚洲第一天堂无码专区| 国产精品高潮呻吟久久av黑人| 国自在线精品视频| 亚洲精品狠狠操| 亚洲色图偷窥自拍| 欧美性生交xxxxx久久久| 国产午夜精品视频免费不卡69堂| 久久色在线播放| 欧美日韩精品在线播放| 国产日韩在线精品av| 91免费高清视频| 欧美视频精品一区| 欧美黄色小视频| 成人免费看片视频| 久久久久久国产免费| 国产91精品青草社区| 亚洲一区二区久久久久久| 久久精品亚洲精品| 欧美高跟鞋交xxxxxhd| 日本欧美国产在线| 久久97久久97精品免视看| 亚洲美女喷白浆| 91精品国产乱码久久久久久蜜臀| 精品国产一区二区三区四区在线观看| 久久青草精品视频免费观看| 少妇精69xxtheporn| 日韩精品视频免费| 国产精品综合不卡av| 国产成人亚洲综合91精品| 国产精品女视频| 一色桃子一区二区| 最近2019年中文视频免费在线观看| 日韩欧美在线观看视频| 在线观看亚洲视频| 中文字幕亚洲图片| 日韩成人高清在线| 欧美成人手机在线| 日韩精品日韩在线观看|