四大组件初始之ContentProvider
在android中,除了存放在外部存储的共享目录下的数据,各个应用的数据库文件,资源等都是私有的,其他应用没有访问权限。所以有了ContentProvider,不包含功能逻辑,用于不同应用进程间共享数据,是数据访问的接口。
一、工作流程
为了快速熟悉ContentProvider的工作流程。先创建一个没有具体实现的ContentProvider。
1、创建ContentProvider
只要继承android提供的ContentProvider并实现抽象方法即可。
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Process;
import android.util.Log;
public class MyContentProvider extends ContentProvider {
private final static String Tag="ContentProvider";
public MyContentProvider() {
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
Log.d(Tag,"................delete");
return 0;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
Log.d(Tag,".................insert");
return null;
}
@Override
public boolean onCreate() {
Log.d(Tag,"..................onCreate,PID="+ Process.myPid());
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
Log.d(Tag,".................query");
return null;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
Log.d(Tag,"...................update");
return 0;
}
}
2、注册
应用的组件都要在清单文件里面注册。

为了说明ContentProvider工作在不同的进程间,使用process属性。
3、访问
使用URI定位一个ContentProvide,URI值为注册时的authorities属性。
import android.content.ContentResolver;
import android.net.Uri;
import android.os.Process;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private final static String Tag="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(Tag,"..............onCreate PID="+ Process.myPid());
Uri uri=Uri.parse("content://org.su.example.contentper");
ContentResolver contentResolver=getContentResolver();
contentResolver.query(uri,null,null,null,null);
contentResolver.query(uri,null,null,null,null);
contentResolver.delete(uri,null,null);
contentResolver.delete(uri,null,null);
}
}
ContentResolver是android提供访问ContentProvide的类。
日志输出


二、数据形式
ContentProvide的接口看起来就像数据库的操作,增删改查。ContentProvide的数据形式也多是组织成表格的形式。每个表有多列。表的一行代表一个记录。这就意味着我们要使用一个ContentProvide还要知道它有哪些表,表结构是什么样的。一般android提供的ContentProvide都有一个说明类。例如访问android的图片的表结构可以通过MediaStore.Images获得,联系人信息通过ContactsContract.Contacts获得。
三、自定义完整的ContentProvider
很多文章的表结构用的是book(id,name,author);
使用SQLiteOpenHelper
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DbOpenHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "book.db";
public static final String TABLE_NAME = "book";
private static final int DB_VERSION = 1;
// book表
private String CREATE_BOOK_TABLE = "CREATE TABLE IF NOT EXISTS "
+ TABLE_NAME + "(_id INTEGER PRIMARY KEY," + "name TEXT,"+" author TEXT)";
public DbOpenHelper(Context context) {
super(context,DB_NAME,null,DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion){
// TODO ignored
}
}
BookProvider代码
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;
public class BookProvider extends ContentProvider {
private static final String TAG = "BookProvider";
public static final String AUTHORITY = "org.su.book.provider";
public static final Uri URI = Uri.parse("content://"
+ AUTHORITY + "/book");
private Context mContext;
private SQLiteDatabase mDb;
@Override
public boolean onCreate() {
Log.d(TAG,"onCreate,current thread:"+ Thread.currentThread().getName());
mContext = getContext();
//初始化数据
initProviderData();
return true;
}
private void initProviderData() {
mDb = new DbOpenHelper(mContext).getWritableDatabase();
mDb.execSQL("delete from " + DbOpenHelper.TABLE_NAME);
mDb.execSQL("insert into book values(3,'Android','Android');");
mDb.execSQL("insert into book values(4,'Ios','Ios');");
mDb.execSQL("insert into book values(5,'Html5','web');");
}
@Override
public Cursor query(Uri uri,String[] projection,String selection,
String[] selectionArgs,String sortOrder) {
String table = getTableName(uri);
if (table == null) {
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
return mDb.query(table,projection,selection,selectionArgs,null,
null,sortOrder,null);
}
@Override
public String getType(Uri uri) {
Log.d(TAG,"getType");
return null;
}
@Override
public Uri insert(Uri uri,ContentValues values) {
Log.d(TAG,"insert");
String table = getTableName(uri);
if (table == null) {
throw new IllegalArgumentException("Unsupported URI: " + uri);
}mDb.insert(table,null,values);
mContext.getContentResolver().notifyChange(uri,null);
return uri;
}
@Override
public int delete(Uri uri,String selection,String[] selectionArgs) {
Log.d(TAG,"delete");
String table = getTableName(uri);
if (table == null) {
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
int count = mDb.delete(table,selection,selectionArgs);
if (count > 0) {
getContext().getContentResolver().notifyChange(uri,null);
}
return count;
}
@Override
public int update(Uri uri,ContentValues values,String selection,
String[] selectionArgs) {Log.d(TAG,"update");
String table = getTableName(uri);
if (table == null) {
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
int row = mDb.update(table,values,selection,selectionArgs);
if (row > 0) {
getContext().getContentResolver().notifyChange(uri,null);
}
return row;
}
private String getTableName(Uri uri) {
String tableName = null;
if(uri.equals(URI))
tableName=DbOpenHelper.TABLE_NAME;
return tableName;
}
}
在MainActivity中访问
Uri uri=Uri.parse("content://org.su.book.provider/book");
ContentResolver contentResolver=getContentResolver();
ContentValues values = new ContentValues();
values.put("_id",6);
values.put("name","程序设计");
values.put("author","c");
contentResolver.insert(uri,values);
Cursor bookCursor =contentResolver.query(uri,new String[]
{"_id","name","author"},null,null,null);
while (bookCursor.moveToNext()) {
int id= bookCursor.getInt(0);
String name = bookCursor.getString(1);
String author =bookCursor.getString(2);
Log.d(Tag,"query book:" +"id ="+id+",name ="+name+",author ="+author);
}
bookCursor.close();
日志输出:

四大组件初始之ContentProvider的更多相关文章
- Android四大组件之一:ContentProvider(内容提供者)
Android中还提供了名为ContentProvider(内容提供者),可以向其他应用提供数据,但不常用,除非是同一公司开发的App,可以向不同应用提供数据.虽然为Android的四大组件之一,但用 ...
- 四大组件初始之Broadcast
在进行应用设计时,需要获取很多环境参数,像电量,音量,亮度,网络等.相比较每次去询问android这些信息改变了吗.让Android告诉我们,这些信息改变了更加合理.只要这些信息改变,Android通 ...
- Android 四大组件学习之ContentProvider五
上几节学习了ContentProvider的实际用途,读取短信.插入短信,读取联系人.插入联系人等. 本节课在学习ContentProvider的观察者. 在生活中有第三方的软件.比方什么短信软件.此 ...
- Android 四大组件学习之ContentProvider二
上节学习了什么是ContentProvider.以及ContentProvider的作用.以及什么是URL.本节就对上节学习的知识做一个实践,也就是定义自己的ContentProvider 好.实践是 ...
- Android 四大组件学习之ContentProvider三
上节课学习怎样自己创建一个ContentProvider.以及用ContentResolver去操作ContentProvider. 今天我们用系统提供的ContentProvider. 先来个简单的 ...
- Android 四大组件学习之ContentProvider四
上节我们学习了怎样去读取系统短信以及插入一条短信到系统中. 本节我们学习怎样获取系统的联系人,以及插入一条联系人 好.废话不多说了,直接操作. 首先和读取短信一样,先找到联系人在数据库中的位置. wa ...
- Android四大组件与进程启动的关系(转)
一. 概述 Android系统将进程做得很友好的封装,对于上层app开发者来说进程几乎是透明的. 了解Android的朋友,一定知道Android四大组件,但对于进程可能会相对较陌生. 一个进程里面可 ...
- 四大组件之ContentProvider
前言 ContentProvider作为Android的四大组件之一,是属于需要掌握的基础知识,可能在我们的应用中,对于Activity和Service这两个组件用的很常见,了解的也很多,但是对Con ...
- 初学android:四大组件之contentprovider
一.ContentProvider的概念ContentProvider:为存储和获取数据提供统一的接口.可以在不同的应用程序之间共享数据.Android已经为常见的一些数据提供了默认的ContentP ...
随机推荐
- pythonday06数据类型(四)
今日内容 1.集合 2内存相关 1.集合set 无序 无重复 v = {1,2,3,4,5,6,99,100} # 疑问:v = {} """ None int v1 = ...
- .netcore持续集成测试篇之Xunit结合netcore内存服务器发送post请求
系列目录 Web项目中,很多与用户数据交互的请求都是Post请求,想必大家都用过HttpClient构造过post请求,这里并不对HttpClient做详细介绍,只介绍一些常用的功能.并结合AutoF ...
- 解决微信二次分享失败--后面被加上from=singlemessage&isappinstalled=0的解决方案
首次分享成功,点开后再次分享或第三次分享就失败了 1.检查你分享的链接,看是否多了两个参数,微信分享会根据分享的不同,为原始链接拼接: 朋友圈 from=timeline&isappins ...
- Java初学心得(一)
Java中基本组成单元是类,在类中又包含属性和方法. 每个应用程序都包含一个main()方法,main方法里的称为主类. 一,基本变化 ①全局变量:在类中的属性 局部变量:在方法中的属性 ②基本数据类 ...
- 解决Selenium弹出新页面无法定位元素问题(Unable to locate element)
Python 2.7 IDE Pycharm 5.0.3 环境细节详见Python+Selenium+PIL+Tesseract真正自动识别验证码进行一键登录 对于同一页面无法定位元素问题请见姊妹篇解 ...
- python实例:自动保存百度盘资源到百度盘中
本实例的实现逻辑是,应用selenium UI自动化登录百度盘,读取存储百度分享地址和提取码的txt文档,打开百度盘分享地址,填入提取码,然后保存到指定的目录中 全部代码如下: # -*-coding ...
- Nacos(六):多环境下如何“管理”及“隔离”配置和服务
前言 前景回顾: Nacos(五):多环境下如何"读取"Nacos中相应环境的配置 Nacos(四):SpringCloud项目中接入Nacos作为配置中心 现如今,在微服务体系中 ...
- 存储型XSS的发现经历和一点绕过思路
再次骚扰 某SRC提现额度竟然最低是两千,而已经有750的我不甘心呐,这不得把这2000拿出来嘛. 之后我就疯狂的挖这个站,偶然发现了一个之前没挖出来的点,还有个存储型XSS! 刚开始来到这个之前挖过 ...
- vuex详解vue简单使用
vue概念:vuex 是 Vue 配套的 公共数据管理工具,它可以把一些共享的数据,保存到 vuex 中,方便 整个程序中的任何组件直接获取或修改我们的公共数据: 配置vuex的步骤: 1.运行cnp ...
- unity之初级必备知识
C#中有两种常见类型:值类型,引用类型.值类型存放在内存中栈里,引用类型在内存中栈里存放引用,实际存放在内存中的堆里.值类型继承自System.ValueType.System.ValueType继承 ...