`
huakewoniu
  • 浏览: 46519 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

content provider 深入解析

阅读更多

       Content providers are one of the primary building blocks of Android applications, providing content to applications. They encapsulate data and provide it to applications through the single ContentResolver interface. A content provider is only required if you need to share data between multiple applications.  If you don't need to share data amongst multiple applications you can use a database directly via SQLiteDatabase.

 

      照我的理解的话,你可以把ContentProvider 当成是一个适配器。 也就是让应用程序能够通过Content provider提供的接口,调用database 提供的接口来访问database中的数据。也就是说用户可以直接使用ContentResolver操作ContentProvider  来间接访问其它应用程序存在database 中的数据。

    下面的例子是实现了这个过程。

一 实现custom content provider  

 

public class ReadingProvider extends ContentProvider {

    public static final String AUTHORITY = ReadingProvider.class.getName().toLowerCase();

 //下面是定义了两个访问类型的常量。
 //访问整张数据表
    private static final int TYPE_ALL_ITEMS           = 1;
    //访问该张表中特定的row的数据
    private static final int TYPE_SINGLE_ITEM         = 2;
   
    //这个contentprovider对应的数据库
    private ReadingOpenHelper dbhelper = null;

 //用来匹配content provider的 Uri
    private static final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);

    static {
        matcher.addURI(AUTHORITY, "items", TYPE_ALL_ITEMS);
  //注意这个# 的意思是占位符,对应的uri可以是这样的形式
  //static final Uri URI = Uri.parse("content://" + ReadingProvider.AUTHORITY + "/items");
  //itemUri = Uri.withAppendedPath(URI, "" + item_id);
        matcher.addURI(AUTHORITY, "items/#", TYPE_SINGLE_ITEM);
    }

 //在这个content provider创建的时候打开数据库
    @Override
    public boolean onCreate() {
     log.debug("readingprovider oncreate");
        dbhelper = new ReadingOpenHelper(getContext());
        return true;
    }
   
    @Override
    public int delete(Uri uri, String where, String[] whereArgs) {
        switch (matcher.match(uri)) {
        case TYPE_ALL_ITEMS:

        //当匹配TYPE_ALL_ITEMS 这个Uri的时候就删掉ItemColumns.TABLE_NAME 这个table中相应的数据
            return dbhelper.getWritableDatabase().delete(ItemColumns.TABLE_NAME, where, whereArgs);
        case TYPE_SINGLE_ITEM:

        //当匹配TYPE_SINGLE_ITEM 这个Uri的时候就删掉ItemColumns.TABLE_NAME 这个table中用id指定的row的数据
            String i_id = uri.getPathSegments().get(1);
            return dbhelper.getWritableDatabase().delete(ItemColumns.TABLE_NAME, ItemColumns._ID + "=" + i_id, null);
        }
        throw new IllegalArgumentException("Unsupported URI: " + uri);
    }

 

    @Override
    public String getType(Uri uri) {
        switch (matcher.match(uri)) {
        case TYPE_ALL_ITEMS:
            return null;//there is no type so return null
        case TYPE_SINGLE_ITEM:
            return null;
        }
        throw new IllegalArgumentException("Unsupported URI: " + uri);
    }
   
    @Override
    public Uri insert(Uri uri, ContentValues initialValues) {
        long id = 0L;
        switch (matcher.match(uri)) {
        case TYPE_ALL_ITEMS:

       //当匹配这个Uri的时候就在(ItemColumns.TABLE_NAME这个table中插入initialValues
            id = dbhelper.getWritableDatabase().insertOrThrow(ItemColumns.TABLE_NAME, null, initialValues);
            return ContentUris.withAppendedId(ItemColumns.URI, id);
        }
        throw new IllegalArgumentException("Illegal Uri: " + uri.toString());
    }

 

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sort) {
     //log.debug("reading provider query" + uri.toString());
     Cursor cursor = null;
        switch (matcher.match(uri)) {
        case TYPE_ALL_ITEMS:
         cursor = dbhelper.getReadableDatabase().query(ItemColumns.TABLE_NAME, projection, selection, selectionArgs, null, null, sort);
         break;
        case TYPE_SINGLE_ITEM:
            String i_id = uri.getPathSegments().get(1);
            cursor = dbhelper.getReadableDatabase().query(ItemColumns.TABLE_NAME, projection, ItemColumns._ID + "=" + i_id, null, null, null, null);
            break;
        default:
            throw new IllegalArgumentException("Illegal Uri: " + uri.toString());
        }
       
        if (cursor != null) {
         cursor.setNotificationUri(getContext().getContentResolver(), uri);
        } else {
            log.warn("query failed in reading provider");
        }
        return cursor;
    }

    @Override
    public int update(Uri uri, ContentValues initialValues, String where, String[] whereArgs) {
        switch (matcher.match(uri)) {
        case TYPE_ALL_ITEMS:
            return dbhelper.getWritableDatabase().update(ItemColumns.TABLE_NAME, initialValues, where, whereArgs);
        }
        throw new IllegalArgumentException("Illegal Uri: " + uri.toString());
    }
}

 

note: 由上面的content provider的实现我们可以看到,content provider的内部都是在对其相关联的那个数据库进行操作。

 

二 下面实现这个数据库。 ReadingOpenHelper  继承 SQLiteOpenHelper,使用父类提供的接口来对自己定义的数据库进行相关的操作

1.

public class ReadingOpenHelper extends SQLiteOpenHelper {
 
 private final Log log = Utils.getLog(getClass());

    public ReadingOpenHelper(Context context) {
        super(context, "bereader.db", null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {    

        //下面是创建一个数据库的sql语句
        String sql_create_item = cat(
                "CREATE TABLE IF NOT EXISTS ", ItemColumns.TABLE_NAME, " (",
                ItemColumns._ID, " INTEGER PRIMARY KEY AUTOINCREMENT, ",
                ItemColumns.TITLE, " VARCHAR(256)"
                ");"
        );
        String sql_index_item_title = cat(
                "CREATE UNIQUE INDEX IDX_",
                ItemColumns.TABLE_NAME,
                "_",
                ItemColumns.TITLE,
                " ON ",
                ItemColumns.TABLE_NAME,
                " (",
                ItemColumns.TITLE,
                ");"
        );

        //执行这个sql语句

        db.execSQL(sql_create_item);
        db.execSQL(sql_index_item_title);
    }
   
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
     log.debug("onUpdate, from: " + oldVersion + " to " + newVersion);
        if (oldVersion!=newVersion) {
            // drop db 更新数据库的时候要先删掉以前的数据库,这里我们调用onCreate(db);
           //来重新生成一个数据库
            db.execSQL(cat("DROP TABLE ", ItemColumns.TABLE_NAME));
            onCreate(db);
        }
    }

 

    String cat(String... ss) {
        StringBuilder sb = new StringBuilder(ss.length << 3);
        for (String s : ss)
            sb.append(s);
        return sb.toString();
    }
}

 

2.下面这个类就是表示数据库中的一个一个item实体,定义了这个item所在的数据表的名字,用来访问这个数据表的Uri,和这个item的field 这里只有一个TITLE

public interface ItemColumns extends BaseColumns {

    //用这个Uri就能够从provider中访问数据库中存储的ItemColumns 的内容

    static final Uri URI = Uri.parse("content://" + ReadingProvider.AUTHORITY + "/items");

    static final String TABLE_NAME = "beReaderItems";
    static final String TITLE = "title";
}

 

三: 下面我们来使用content provider来访问数据库中的数据。

void testProvider(){

 

      ContentValues cv = new ContentValues();
    ContentResolver cr = getContentResolver();
    
     cv.put(ItemColumns.TABLE_NAME, "title_name1");
     //插入一条item

     cr.insert(ItemColumns.URI,cv);
     //查询指定的item

     String itemUri = Uri.withAppendedPath(ItemColumns.URI, "" + item_id);
    Cursor cursor = cr.query(itemUri,
      new String [] {ItemColumns._ID,ItemColumns.TITLE,},
      null, null, null);

    

//更新一条记录

      cv.put(ItemColumns.TABLE_NAME, "title_name1");
        int n = cr.update(
                ItemColumns.URI,
                cv,
                ItemColumns.URI._ID + "=" + itemId,
                null
        );     
 }

分享到:
评论

相关推荐

    Android学习笔记之ContentProvider和Uri详解

    本文介绍了自定义Content Provider的相关内容,完全解析内容提供者的用法。Content Provider,内容提供者,相信大家对这个组件的名字都不陌生,可能是自己平时做的都是一些简单的App,所以对于Content Provider的...

    Android开发艺术探索

    Content Provider / 91 2.4.6 使用Socket / 103 2.5 Binder连接池 / 112 2.6 选用合适的IPC方式 / 121 第3章 View的事件体系 / 122 3.1 View基础知识 / 122 3.1.1 什么是View / 123 3.1.2 View的位置...

    android开发艺术探索高清完整版PDF

    71 2.4.5 使用 Content Provider / 91 2.4.6 使用Socket / 103 2.5 Binder连接池 / 112 2.6 选用合适的IPC方式 / 121 第3章 View的事件体系 / 122 3.1 View基础知识 / 122 3.1.1 什么是View / 123 3.1.2 View...

    Google Android SDK开发范例大全(PDF高清完整版3)(4-3)

    深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...

    Google Android SDK开发范例大全(PDF完整版4)(4-4)

    深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...

    Google Android SDK开发范例大全(PDF高清完整版1)(4-1)

    深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...

    Google Android开发入门与实战的代码

    6.2.4 Content Provider介绍 61 6.3 Android应用工程文件组成 61 6.4 本章小结 62 第7章 良好的学习开端——Android基本组件介绍 63 7.1 第一印象很重要——界面UI元素介绍 63 7.1.1 视图组件(View)...

    Google Android SDK开发范例大全的目录

    深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...

    Google+Android+SDK开发范例大全

    深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(HelloAndroid...

    Google Android SDK开发范例大全(完整版附部分源码).pdf

    深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目...

    《Google Android开发入门与实战》.pdf

    6.2.4 content provider介绍 61 6.3 android应用工程文件组成 61 6.4 本章小结 62 第7章 良好的学习开端——android基本组件介绍 63 7.1 第一印象很重要——界面ui元素介绍 63 7.1.1 视图组件(view)...

    Google Android sdk 开发范例大全 部分章节代码

    深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...

    Google Android SDK 开发范例大全01

    深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...

    Google Android SDK 开发范例大全02

    深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...

    Google Android SDK开发范例大全(完整版)

    深入.动手做. 1.1 红透半边天的Android 1.2 本书目的及涵盖范例范围 1.3 如何阅读本书 1.4 使用本书范例 1.5 参考网站 第2章 Android初体验 2.1 安装AndroidSDK与ADTplug-in 2.2 建立第一个Android项目(Hello...

Global site tag (gtag.js) - Google Analytics