四大组件初始之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 ...
随机推荐
- python案例:使用if语句实现一个猜拳游戏
任务要求: 在控制台中提示输入石头.剪刀.布,按回车键,然后给出游戏结果. 分析: 我们知道在游戏规则中,石头克剪刀,剪刀克布,布克石头.但是这在计算机中并不是很好直接的表示,因此我们分别用0.1.2 ...
- java封装 redis 操作 对象,list集合 ,json串
/** * 功能说明: * 功能作者: * 创建日期: * 版权归属:每特教育|蚂蚁课堂所有 www.itmayiedu.com */package com.redis.service; import ...
- 工作中常见的五种技术leader
力不从心型 在工作中有种技术leader,总认为自己是最好的.在方案设计的时候,自己有一种方案,下属有一种方案.leader非要别人听他的.如果两种方案没有优劣之分,比较建议的做法是让真正实施的人按照 ...
- 8.7 day28 网络编程 socket套接字 半连接池 通信循环 粘包问题 struct模块
前置知识:不同计算机程序之间的数据传输 应用程序中的数据都是从程序所在计算机内存中读取的. 内存中的数据是从硬盘读取或者网络传输过来的 不同计算机程序数据传输需要经过七层协议物理连接介质才能到达目标程 ...
- Spring系列(四):Spring AOP详解
一.AOP是什么 AOP(面向切面编程),可以说是一种编程思想,其中的Spring AOP和AspectJ都是现实了这种编程思想.相对OOP(面向过程编程)来说,提供了另外一种编程方式,对于OOP过程 ...
- idea 2019安装完(打不开&&启动不了)问题解决(最全解决方法)
今天从网盘把idea下载下来后一路安装,准备 设置的时候不管怎么打开 他都无动于衷没办法,卸了安,安了卸,反复折腾了 好几遍 它都无动于衷.于是开始在百度上找答案看了 好几个 方法一遍一遍试还是不行, ...
- ID转名称到手方案01
> 好久没有写技术文章了,那就重新捡起来,从今天开始,分享这段时间的收获吧 ------------ > ## 其实很多时候,我们只需要鱼,而不是渔,呐,给你鱼. ### 这次的分享主题是 ...
- ceph存储基础概念
一.分布式文件系统: 是指文件系统管理的物理存储资源不一定直接是连接在本地节点上,而是通过计算机网络与节点相连. 分布式文件系统的设计基与C/S架构(客户端/服务器) 常见的分布式文件系统:Ceph. ...
- 记录一则DG遭遇ORA-00088的案例
测试环境:RHEL 5.4 + Oracle 11.2.0.3 DG 现象:起初是在使用DG Broker进行switchover切换测试时,报错ORA-16775,提示有可能有数据丢失,不允许swi ...
- Java 迭代接口:Iterator、ListIterator 和 Spliterator
1. 简介 当我们使用 for 或 while 循环来遍历一个集合的元素,Iterator 允许我们不用担心索引位置,甚至让我们不仅仅是遍历一个集合,同时还可以改变它.例如,你如果要删除循环中的元素, ...