`
huakewoniu
  • 浏览: 47656 次
  • 性别: 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
        );     
 }

分享到:
评论

相关推荐

    content_provider_demo

    在Android开发中,Content Provider是一种重要的组件,它允许应用程序之间共享数据。`content_provider_demo`是一个展示如何创建和使用Content Provider的示例项目。在这个项目中,开发者将学习如何为其他应用提供...

    Content Provider获取联系人和图片

    本篇文章将深入探讨如何利用Content Provider获取联系人和图片,以及相关的知识点。 首先,我们要了解Content Provider的基本结构。一个Content Provider由一系列的Uri(统一资源标识符)来定义其数据范围,每个Uri...

    Android基础 Content Provider

    本文将深入探讨Content Provider的基本概念、创建方法、如何进行CRUD(Create、Read、Update、Delete)操作,以及如何访问和监听Content Provider的数据变化,并通过实际案例分析如何使用Content Provider处理短信和...

    编写content provider

    这篇博客“编写Content Provider”很可能是深入解析如何创建和使用自定义Content Provider的教程。Content Provider对于Android开发者来说非常重要,因为它提供了标准的接口,使得数据管理变得规范化和模块化。 ...

    自定义Content Provider

    在Android系统中,Content Provider是一种重要的组件,它允许应用程序之间共享数据。自定义Content Provider是开发者根据自身需求创建的一种机制,使得应用的数据可以被其他应用访问和操作。本篇文章将详细探讨如何...

    2011.09.07(5)——— android 跨进程通信之content provider + AutoCompleteTextView

    首先,我们来深入理解Content Provider。Content Provider是Android系统中数据共享的标准接口,它允许不同的应用访问存储在SQLite数据库、文件系统或者其他任何形式的数据。创建一个Content Provider需要实现以下几...

    深入解析Android 5.0系统 ,刘超著 _高清.pdf

    - **Content Provider**: 分析Content Provider的用途,以及如何通过它实现数据共享。 #### 4. 性能优化 - **内存管理**: 讨论Android 5.0中的内存管理策略,包括垃圾回收机制的改进。 - **多线程编程**: 探讨如何...

    Content-Provider-Kotlin

    在这个项目中,我们将深入探讨如何利用Kotlin的优势来创建、读取和操作Content Provider。 在Android中,Content Provider扮演着数据管理者的角色,它为其他应用提供了统一的数据访问接口。这使得即使数据存储在...

    Android应用源码之30.Content_Providers(2).zip

    在Content Provider类中,你需要定义一个`UriMatcher`来解析和匹配来自其他应用的URI请求。`UriMatcher`会为每个不同的数据路径分配一个独特的代码,便于后续处理。 3. **AndroidManifest.xml注册**:在应用的...

    Android Content Provider详解及示例代码

    本文将深入解析Content Provider的工作原理,并通过实例代码展示如何创建和使用Content Provider。 一、Content Provider 简介 Content Provider作为Android四大组件之一,它的主要职责是管理和暴露数据。每个...

    Content_Providers

    2. **URI解析**:应用通过调用ContentResolver的query()、insert()、update()或delete()方法,传入特定的URI来访问Content Provider。 3. **操作请求**:ContentResolver将这些请求转发给对应的Content Provider。 ...

    应用源码之30.Content_Providers(2).zip

    本压缩包“应用源码之30.Content_Providers(2).zip”很可能是为了深入解析Content Provider的工作原理和使用方法,通过实际的源码示例来帮助开发者提升技能。 Content Providers的核心职责在于管理应用程序的数据...

    应用源码之29.Content_Providers(1).zip

    通过阅读和分析这个“应用源码之29.Content_Providers(1)”的源码,开发者可以深入了解Content Provider的工作原理,掌握如何创建自定义Content Provider,以及如何在不同应用之间共享数据。同时,这也有助于提高对...

    浅谈Android Content Provider的使用

    《深入解析Android Content Provider的使用》 Content Provider作为Android四大组件之一,是Android系统中实现数据共享的关键机制。本文将详细阐述Content Provider的定义、配置、功能以及如何通过Uri进行数据操作...

    Service与Provider

    Content Provider是Android系统中数据共享和交换的桥梁,它可以将数据暴露给其他应用,使得跨应用的数据访问成为可能。常见的使用场景包括读写联系人、日历等系统数据,或者应用间的文件分享。 创建Content ...

    content_provider:使用sqlite android

    总结来说,本项目“content_provider:使用sqlite android”将深入讲解如何结合SQLite数据库和Content Provider,实现Android应用间的数据共享和管理。通过学习和实践,开发者不仅可以掌握Android数据存储的核心技术...

    Dictionary:使用 Content Provider 访问 user_dictionay

    本主题将深入讲解如何使用Content Provider访问`user_dictionay`,以便显示输入单词的频率。`user_dictionay`通常指的是用户自定义的词典,存储着用户输入的个性化单词及其出现的次数或相关信息。 1. **Content ...

    Android 7.0 应用间共享文件FileProvider代码

    本篇文章将深入探讨`FileProvider`的工作原理以及如何在Android 7.0中使用它来实现应用间的文件共享。 一、FileProvider概述 `FileProvider`是Content Provider的一个子类,它提供了一种方式来安全地共享私有文件,...

    技术关键:Android应用开发的核心要素与深入解析.zip

    本文将深入解析Android应用开发的关键知识点,旨在帮助初学者快速上手,同时也为有经验的开发者提供进一步深化理解的参考。 一、Android系统架构 Android系统由Linux内核为基础,上层包括运行库、应用程序框架和...

    Contact Provider练习应用

    总的来说,"Contact Provider练习应用"是一个全面了解和实践ContentProvider的好项目,通过它,你可以深入理解Android中数据共享的机制,为后续的多应用协作开发打下坚实的基础。同时,这也是一种提升Android编程...

Global site tag (gtag.js) - Google Analytics