博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
四大组件之一 CotentProvider
阅读量:5944 次
发布时间:2019-06-19

本文共 6756 字,大约阅读时间需要 22 分钟。

概念

ContentProvider作为四大组件之一,他的地位不容忽视。它的作用是为不同应用程序数据共享,提供统一接口 我们其他应用程序要调用android系统中的应用,这时候就要用到ContentProvider,也可以我们利用ContentProvider编写自己的内容提供者,供其他应用使用

ContentProvider如何实现数据共享的

ContentProvider通过URI唯一标识其他要访问的数据,开发人员一般通过ContentResolver来进行操作ContentProvider,可进行增删改查实现对数据的共享。

ContentProvider讲解

ContentProvider是一个抽象类,如果要开发自己的内容提供者都要继承这个类并进行重写。主要实现以下方法:

public boolean onCreate()

在创建ContentProvider的时候进行调用

public Cursor query()

用来查询指定的URI返回一个Cursor

public Uri insert()

向指定RUI的ContentProvider中插入数据

public int update()

用户更新指定的RUI的数据

public int delete()

用户删除指定的RUI的数据

public String getType()

用于返回指定的Uri中的数据MIME类型

自定义ContentProvider讲解

我们创建一个数据库的ContentProvider类来实现数据共享,自定义名称为MyProvider

package com.haolin.contentprovider.sample;import android.content.ContentProvider;import android.content.ContentValues;import android.content.Context;import android.content.UriMatcher;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.net.Uri;public class MyProvider extends ContentProvider {  private Context mContext;  DBHelper mDbHelper = null;  SQLiteDatabase db = null;  public static final String AUTOHORITY = "com.haolin.contentprovider.sample.MyProvider";  // 设置ContentProvider的唯一标识  public static final int User_Code = 1;  public static final int Job_Code = 2;  // UriMatcher类使用:在ContentProvider 中注册URI  private static final UriMatcher mMatcher;  static{      mMatcher = new UriMatcher(UriMatcher.NO_MATCH);      // 初始化      mMatcher.addURI(AUTOHORITY,"user", User_Code);      mMatcher.addURI(AUTOHORITY, "job", Job_Code);  }  // 以下是ContentProvider的6个方法  /**   * 初始化ContentProvider   */  @Override  public boolean onCreate() {      mContext = getContext();      // 在ContentProvider创建时对数据库进行初始化      // 运行在主线程,故不能做耗时操作,此处仅作展示      mDbHelper = new DBHelper(getContext());      db = mDbHelper.getWritableDatabase();      // 初始化两个表的数据(先清空两个表,再各加入一个记录)      db.execSQL("delete from user");      db.execSQL("insert into user values(1,'Carson');");      db.execSQL("insert into user values(2,'Kobe');");      db.execSQL("delete from job");      db.execSQL("insert into job values(1,'Android');");      db.execSQL("insert into job values(2,'iOS');");      return true;  }  /**   * 添加数据   */  @Override  public Uri insert(Uri uri, ContentValues values) {      // 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名      // 该方法在最下面      String table = getTableName(uri);      // 向该表添加数据      db.insert(table, null, values);      // 当该URI的ContentProvider数据发生变化时,通知外界(即访问该ContentProvider数据的访问者)      mContext.getContentResolver().notifyChange(uri, null);//        // 通过ContentUris类从URL中获取ID//        long personid = ContentUris.parseId(uri);//        System.out.println(personid);      return uri;      }  /**   * 查询数据   */  @Override  public Cursor query(Uri uri, String[] projection, String selection,                      String[] selectionArgs, String sortOrder) {      // 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名      // 该方法在最下面      String table = getTableName(uri);      // 查询数据      return db.query(table,projection,selection,selectionArgs,null,null,sortOrder,null);  }  /**   * 更新数据   */  @Override  public int update(Uri uri, ContentValues values, String selection,                    String[] selectionArgs) {      // 由于不展示,此处不作展开      return 0;  }  /**   * 删除数据   */  @Override  public int delete(Uri uri, String selection, String[] selectionArgs) {      // 由于不展示,此处不作展开      return 0;  }  @Override  public String getType(Uri uri) {      // 由于不展示,此处不作展开      return null;  }  /**   * 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名   */  private String getTableName(Uri uri){      String tableName = null;      switch (mMatcher.match(uri)) {          case User_Code:              tableName = DBHelper.USER_TABLE_NAME;              break;          case Job_Code:              tableName = DBHelper.JOB_TABLE_NAME;              break;      }      return tableName;      }  }复制代码
  • ContentProvider作为四大组件之一,我们必须再AndroidManifest.xml文件中进行注册
复制代码

这里的authorities唯一标识该内容提供者,这样其它的应用才可以找到该内容提供者并操作它的数据;exported为true当前内容提供者可以被其它应用使用,默认为true

操作ContentProvider里的数据

我们在MainActivity中来操作ContentProvider数据 或者新建个项目也可直接操作

/*       * 对user表进行操作       */      // 设置URI      Uri uri_user = Uri.parse("content://com.haolin.contentprovider.sample.MyProvider/user");      // 插入表中数据      ContentValues values = new ContentValues();      values.put("_id", 3);      values.put("name", "Iverson");      // 获取ContentResolver      ContentResolver resolver =  getContentResolver();      // 通过ContentResolver 根据URI 向ContentProvider中插入数据      resolver.insert(uri_user,values);      // 通过ContentResolver 向ContentProvider中查询数据      Cursor cursor = resolver.query(uri_user, new String[]{
"_id","name"}, null, null, null); assert cursor != null; while (cursor.moveToNext()){ System.out.println("query book:" + cursor.getInt(0) +" "+ cursor.getString(1)); // 将表中数据全部输出 } cursor.close(); // 关闭游标 /* * 对job表进行操作 */ // 和上述类似,只是URI需要更改,从而匹配不同的URI CODE,从而找到不同的数据资源 Uri uri_job = Uri.parse("content://com.haolin.contentprovider.sample.MyProvider/job"); // 插入表中数据 ContentValues values2 = new ContentValues(); values2.put("_id", 3); values2.put("job", "NBA Player"); // 获取ContentResolver ContentResolver resolver2 = getContentResolver(); // 通过ContentResolver 根据URI 向ContentProvider中插入数据 resolver2.insert(uri_job,values2); // 通过ContentResolver 向ContentProvider中查询数据 Cursor cursor2 = resolver2.query(uri_job, new String[]{
"_id","job"}, null, null, null); assert cursor2 != null; while (cursor2.moveToNext()){ System.out.println("query job:" + cursor2.getInt(0) +" "+ cursor2.getString(1)); // 将表中数据全部输出 } cursor2.close(); // 关闭游标 复制代码

这样我们可以对ContentProvider进行增删改查等操作。

ContentObserver

  • 注册ContentObserver来监听对应uri的数据变化,这步不是必须的,如果不需要监听数据变化也可以不注册

  • 首先获取ContentResolver对象 getContentResolver() 在进行注册Observer resolver.registerContentObserver(uri_user,true,new TestContentObs(handler));

  • 我们需要创建个类继承ContentObserver

package com.haolin.contentprovider.testcontentprovider;import android.database.ContentObserver;import android.net.Uri;import android.os.Handler;import android.os.Message;/*** 作者:haoLin_Lee on 2019/05/12 12:18* 邮箱:Lhaolin0304@sina.com* class:*/public class TestContentObs extends ContentObserver {  Handler handler;  public TestContentObs(Handler handler) {      super(handler);      this.handler = handler;  }  @Override  public void onChange(boolean selfChange, Uri uri) {      super.onChange(selfChange, uri);      Message message = Message.obtain();      message.obj = uri;      handler.sendMessage(message);  }}复制代码

如果数据库内容有更新,ContentObserver在收到数据变化的通知后通过Handler机制来通知主线程更新UI

感谢大家的阅读

给个赞呗 有问题及时反馈,谢谢大家

关注我

转载地址:http://yzkxx.baihongyu.com/

你可能感兴趣的文章
ASP.net MVC 中Security.FormsAuthentication验证用户的状态(匿名|已登录)
查看>>
《C++ Primer》 Part III(Classes and Data Abstraction)
查看>>
FriendlyUrls——在ASP.NET Web表单中使用更友好的URL
查看>>
NodeJs新手学习笔记之工具准备
查看>>
SQL ExecuteNonQuery()的返回值
查看>>
【函数】strcpy源代码
查看>>
【javascript】字符串对象常用 api
查看>>
对PostgreSQL中 index only scan 的初步理解
查看>>
poj 2337 Catenyms
查看>>
PypeR
查看>>
新浪微博布局学习——活用RelativeLayout
查看>>
第46周星期二
查看>>
Tomcat虚拟子目录
查看>>
REVIT参数化有什么意义
查看>>
将python3.1+pyqt4打包成exe
查看>>
解释器中对 标号 的使用
查看>>
分享:FireBreath 1.7.0 RC1 发布
查看>>
<<Information Store and Management>>读书笔记 之五
查看>>
2012年50个顶级的photoshop教程:(一)图形绘画类
查看>>
数据库和c#类型映射
查看>>