什么是ContentProvider:

ContentProvider用来管理数据的访问规则。它允许你的应用程序向外界暴露需要被访问的数据。

是Android的四大组件之一。

ContentProviders支持四种基本的操作,即我们平时所见到的CRUD操作(增删改查)。Android系统

本身已经提供了一些内容提供者,它们允许我们查询联系人,媒体库,和短息消息等。

基于Content Uri的查询:

没有Uri,ContentProvider 类基本无法工作,就像我们上网没有网址。当我们要上网,就要在地址栏输入网址。

因此,要了解ContentProvider,我们必须先了解 Content Uri

下面是Uri的基本格式:

  1. content://authority/optionalPath/optionalId

content://是内容提供者的标准前缀,而且它必须是content://。authority由我们自己定义,它必须具有唯一性,

因此我们一般使用应用程序包名命名authority。optionalPath和optionalId是可选的。

下面我们来看一下WordPress的文章地址格式:

http://www.whathecode.com/archives/221

http:// 是http协议的标准写法,它是规定的,没有为什么。

www.whathecode.com可以理解为authority,因为域名是唯一的,它可以分辨我们要访问哪一个网站。

arichives可以理解为文章的分类。

最后的221就是文章的id,假如我们要查看第一遍文章,只要将221改成1就可以。

这样理解Uri是不是简单了很多。

建立自己的ContentProvider

建立ContentProvider只需几部:

1. 设计数据库的储存方式,因为ContentProvider提供的是数据,没有数据,ContentProvider就没有了用处。

2. 定义自己的类,继承ContentProvider类,并实现基本的方法。

3. 设计authority字符串。(要被人访问你的网站,你就需要一个网址,当然ip地址也可以)

4. 在AndroidManifest中注册Provider

我们先来研究一下代码:

作为示例下面的代码只实现了query方法,而且只添加了一个Uri,

一般应用程序都不只一个Uri

  1. package com.whathecode.provider;
  2.  
  3. import android.content.ContentProvider;
  4. import android.content.ContentValues;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.content.UriMatcher;
  8. import android.database.Cursor;
  9. import android.database.sqlite.SQLiteDatabase;
  10. import android.database.sqlite.SQLiteDatabase.CursorFactory;
  11. import android.database.sqlite.SQLiteOpenHelper;
  12. import android.net.Uri;
  13. import android.util.Log;
  14. import android.widget.Toast;
  15.  
  16. public class MemberProvider extends ContentProvider
  17. {
  18.  
  19. private static final UriMatcher sMatcher;
  20. private static final String MEMBER_NAME = "name";
  21. private static final int QUERY_BY_NAME = 0;
  22. private static final String DB_NAME = "member.db";
  23. private static final String TAG = "MemberProvider";
  24.  
  25. static
  26. {
  27. sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  28. /**
  29. * 添加需要匹配的Uri, 当这个Uri被匹配的时候返回第三个参数。
  30. * 得到这个参数之后就可以在query,insert,update,delete
  31. * 方法中做出相应的动作。
  32. */
  33. sMatcher.addURI(Member.AUTHORITY, MEMBER_NAME, QUERY_BY_NAME);
  34. }
  35.  
  36. private static class DataBaseHelper extends SQLiteOpenHelper
  37. {
  38.  
  39. public DataBaseHelper(Context context, String name,
  40. CursorFactory factory, int version)
  41. {
  42. super(context, name, factory, version);
  43. }
  44.  
  45. @Override
  46. public void onCreate(SQLiteDatabase db)
  47. {
  48. //建立数据库表结构
  49. db.execSQL("create table member(_id integer primary key," +
  50. "name varchar(20)," +
  51. "work varchar(20)," +
  52. "age integer)");
  53. }
  54.  
  55. @Override
  56. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
  57. {
  58. // TODO Auto-generated method stub
  59.  
  60. }
  61.  
  62. }
  63.  
  64. private DataBaseHelper mHelper;
  65.  
  66. @Override
  67. public boolean onCreate()
  68. {
  69. mHelper = new DataBaseHelper(getContext(), DB_NAME, null, 2);
  70. return true;
  71. }
  72.  
  73. @Override
  74. public Cursor query(Uri uri, String[] projection, String selection,
  75. String[] selectionArgs, String sortOrder)
  76. {
  77.  
  78. /**
  79. * 前面我们在静态代码块中已添加了Uri库
  80. * 当每个Uri作为参数传进来的时候我们都先进行匹配
  81. *
  82. */
  83. switch (sMatcher.match(uri))
  84. {
  85. case QUERY_BY_NAME:
  86. //第一次执行时生成数据库member.db
  87. SQLiteDatabase readableDatabase = mHelper.getReadableDatabase();
  88. /**
  89. * 当query方法执行的时候向外发送广播
  90. */
  91. Intent intent = new Intent();
  92. intent.setAction("com.contentprovider.execquery");
  93. intent.putExtra("MemberProvider", "query方法执行了");
  94. getContext().sendBroadcast(intent);
  95. break;
  96.  
  97. default:
  98. /**
  99. * 当Uri匹配失败的时候说明Uri参数错误,无法继续进行操作,
  100. * 因此程序抛出一个错误
  101. */
  102. throw new IllegalArgumentException("Unknown URI " + uri);
  103. }
  104. return null;
  105. }
  106.  
  107. @Override
  108. public String getType(Uri uri)
  109. {
  110. // TODO Auto-generated method stub
  111. return null;
  112. }
  113.  
  114. @Override
  115. public Uri insert(Uri uri, ContentValues values)
  116. {
  117. // TODO Auto-generated method stub
  118. return null;
  119. }
  120.  
  121. @Override
  122. public int delete(Uri uri, String selection, String[] selectionArgs)
  123. {
  124. // TODO Auto-generated method stub
  125. return 0;
  126. }
  127.  
  128. @Override
  129. public int update(Uri uri, ContentValues values, String selection,
  130. String[] selectionArgs)
  131. {
  132. // TODO Auto-generated method stub
  133. return 0;
  134. }
  135.  
  136. }

这样,一个虽简单但可行的内容提供者就创建好了,现在我们只需在AndroidManifest文件中注册它。

  1. <provider android:name="com.whathecode.provider.MemberProvider"
  2. android:authorities="com.whathecode.contentproviderdemo.member">
  3. </provider>

接下来,运行这个程序,将我们刚才定义的ContentProvider部署到模拟器。

然后,我们建立另外一个程序测试这个内容提供者是否真的工作正常。

下面是另外一个程序的代码:

我们需要另外一个类进行访问ContentProvider提供的数据。

这个类就是ContentResolver,它提供了和ContentProvider一样的CRUD方法。

方便我们查询数据。

  1. package com.whathecode.contentprovidertest;
  2.  
  3. import android.app.Activity;
  4. import android.content.BroadcastReceiver;
  5. import android.content.ContentResolver;
  6. import android.content.Context;
  7. import android.content.Intent;
  8. import android.content.IntentFilter;
  9. import android.net.Uri;
  10. import android.os.Bundle;
  11. import android.view.View;
  12. import android.widget.Toast;
  13.  
  14. public class MainActivity extends Activity
  15. {
  16.  
  17. private BroadcastReceiver receiver;
  18. @Override
  19. protected void onCreate(Bundle savedInstanceState)
  20. {
  21. super.onCreate(savedInstanceState);
  22. setContentView(R.layout.activity_main);
  23.  
  24. //创建一个广播接受者用于接收MemberProvider发出的广播
  25. receiver = new BroadcastReceiver()
  26. {
  27.  
  28. @Override
  29. public void onReceive(Context context, Intent intent)
  30. {
  31. /**
  32. * 当广播被接收到的时候Toast提示用户接收到的信息
  33. */
  34. Toast.makeText(getBaseContext(),
  35. "收到的信息" + intent.getStringExtra("MemberProvider"),
  36. Toast.LENGTH_SHORT).show();
  37. }
  38. };
  39. }
  40.  
  41. @Override
  42. protected void onResume()
  43. {
  44. super.onResume();
  45. //注册广播接受者
  46. registerReceiver(receiver, new IntentFilter("com.contentprovider.execquery"));
  47. }
  48.  
  49. public void onClick(View view)
  50. {
  51. /**
  52. * 获取ContentResolver实例访问ContentProvider
  53. */
  54. ContentResolver resolver = getContentResolver();
  55. Uri uri = Uri
  56. .parse("content://com.whathecode.contentproviderdemo.member/name");
  57. resolver.query(uri, null, null, null, null);
  58. }
  59.  
  60. @Override
  61. protected void onPause()
  62. {
  63. super.onPause();
  64. //取消注册广播接受者
  65. unregisterReceiver(receiver);
  66. }
  67. }

运行效果:

如果Toast运行证明MemberProvider中的query方法被成功执行

使用ContentProvider进行应用程序间的数据交互的更多相关文章

  1. contentprovider提供程序间共享数据的统一接口

    contentprovider提供程序间共享数据的统一接口

  2. iPhone应用程序间传递数据

    前一篇简单的介绍了iPhone应用程序间通信,主要是通过在被调用应用的Info.plist中加入URL方案,在应用中通过openUrl来实现程序的调用.而应用程序间的数据传递则可以更具url来实现,例 ...

  3. Windows窗体间的数据交互

    轻松掌握Windows窗体间的数据交互                                     作者:郑佐 2004-04-05 Windows 窗体是用于 Microsoft Win ...

  4. View与Control间的数据交互

    View与Control间的数据交互 1.ViewBag.Name ="Name1" 2.ViewData["VD"] = "view data&qu ...

  5. linux 共享内存shm_open实现进程间大数据交互

    linux 共享内存shm_open实现进程间大数据交互 read.c #include <sys/types.h> #include <sys/stat.h> #includ ...

  6. iOS应用程序间共享数据

    我们知道iOS由于沙盒的存在,应用程序不能越过自己的区域去访问别的存储空间的内容,不过可能有许多场景我们需要在应用程序之间共享数据,比如多个应用共用用户名密码进行登录等.虽然我们不能直接通过文件系统来 ...

  7. python的进程间的数据交互

    #先来看下如何实现多进程 # multiprocessing 这个是python的多进程的模块,我们会用到这个模块的很多方法 from multiprocessing import Process i ...

  8. 【python】-- 多进程的基本语法 、进程间数据交互与共享、进程锁和进程池的使用

    多进程 进程之间是相互独立的,python是启动进程的时候,是启动的是原生进程.进程是没有GIL锁的,而且不存在锁的概念,进程之间的数据式不能共享的,而线程是可以的. 1.进程的定义 用mulipro ...

  9. Hybrid小程序混合开发之路 - 数据交互

    HTML+CSS是历史悠久.超高自由度.控制精准.表现能力极强.编码简单.学习门槛超低.真跨平台的一种UI界面开发方式. 本文介绍的是微信小程序和H5混合开发的一种数据交互方式. 很多应用在原生界面中 ...

随机推荐

  1. To create my first app in iOS with Xcode(在Xcode创建我的第一个iOS app )

    To create my first app in iOS create the project. In the welcome window, click “Create a new Xcode p ...

  2. memcached在windows下多实例并存

    文章来源:http://blog.csdn.net/xingxing513234072/article/details/39343999 memcached.exe的-d install命令安装时其他 ...

  3. arc如何破循环或交叉引用

    IOS两种常见的循环引用: 1,两个类之间互相定义对方的引用 如下: //ARC code @interface A : NSObject @property (nonatomic,strong) B ...

  4. NET Core中实现一个Token base的身份认证

    NET Core中实现一个Token base的身份认证 注:本文提到的代码示例下载地址> How to achieve a bearer token authentication and au ...

  5. (转)linux下vi命令大全

    http://www.cnblogs.com/88999660/articles/1581524.html 进入vi的命令 vi filename :打开或新建文件,并将光标置于第一行首 vi +n ...

  6. 怎么实现ZBrush中Alt键和Shift键的灵活运用

    ZBrush是一个数字雕刻和绘画软件,它以强大的功能和直观的工作流程彻底改变了整个三维雕刻行业.在一个简洁的界面中,ZBrush为当代数字艺术家提供了世界上最先进的工具.利用快捷键能使操作更快捷高效, ...

  7. jquery.roundabout.js实现3D图片层叠旋转木马切换

    最近项目中需要实现3D图片层叠旋转木马切换的效果,于是用到了jquery.roundabout.js. 兼容性如图: html结构代码: <div id="featured-area& ...

  8. u3d_shader_surface_shader_1

    http://docs.unity3d.com/Manual/SL-SurfaceShaders.html 一:surface shader是啥 Writing shaders that intera ...

  9. session跨域和ajax跨域名

    后台跨域和ajax跨域名: 后台跨域: www.baidu.com   主域名(一级域名一般以www开头) news.baidu.com   二级域名 (a.test.com和b.test.com有相 ...

  10. Cornerstone 哪些错误

    1.Unable to connect to a repository at URl.............,The operation could not be completed 说明无法连接的 ...