ContentProvider解析

2024-05-27 06:48
文章标签 解析 contentprovider

本文主要是介绍ContentProvider解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.ContentProvider是什么:
四大组件之一用于共享数据。多个进程间共享数据,可以通过共享文件的方法,而共享文件的话,权限自己怎么控制呢?ContentProvider让开发者能够在拥有读写权限的情况下通过一条地址(比如content://com.fool/tab1)来访问共享数据。

2.应用场景 android 中许多系统软件和应用软件都使用该方式实现数据共享,比如电话本,相片,音乐,短彩信,日程表信息等

3.ContentProvider使用代码
AndroidManifest.xml中

<!--android:authorities 唯一标识,通过这个标识外部应用访问BookProvider,因此必须是唯一的,建议加上包前缀-->
<!--android:permission 如果外界想访问BookProvider就必须添加这个权限-->
<provider
    android:name=".provider.BookProvider"android:authorities="com.ryg.chapter_2.book.provider" android:permission="com.ryg.PROVIDER"android:process=":provider" >
</provider>

辅助数据库类 DbOpenHelper.java

public class DbOpenHelper extends SQLiteOpenHelper {private static final String DB_NAME = "book_provider.db";public static final String BOOK_TABLE_NAME = "book";public static final String USER_TALBE_NAME = "user";private static final int DB_VERSION = 3;private String CREATE_BOOK_TABLE = "CREATE TABLE IF NOT EXISTS "+ BOOK_TABLE_NAME + "(_id INTEGER PRIMARY KEY," + "name TEXT)";private String CREATE_USER_TABLE = "CREATE TABLE IF NOT EXISTS "+ USER_TALBE_NAME + "(_id INTEGER PRIMARY KEY," + "name TEXT,"+ "sex INT)";public DbOpenHelper(Context context) {super(context, DB_NAME, null, DB_VERSION);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_BOOK_TABLE);db.execSQL(CREATE_USER_TABLE);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// TODO ignored}}

BookProvider .java

public class BookProvider extends ContentProvider {private static final String TAG = "BookProvider";public static final String AUTHORITY = "com.ryg.chapter_2.book.provider";public static final Uri BOOK_CONTENT_URI = Uri.parse("content://"+ AUTHORITY + "/book");public static final Uri USER_CONTENT_URI = Uri.parse("content://"+ AUTHORITY + "/user");public static final int BOOK_URI_CODE = 0;public static final int USER_URI_CODE = 1;private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);static {//因为BookProvider对应操作的有两张表,所以通过以下方法让他们关联不同的URI_CODE//再通过getTableName来匹配不同的表sUriMatcher.addURI(AUTHORITY, "book", BOOK_URI_CODE);sUriMatcher.addURI(AUTHORITY, "user", USER_URI_CODE);}private Context mContext;private SQLiteDatabase mDb;@Overridepublic 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.BOOK_TABLE_NAME);mDb.execSQL("delete from " + DbOpenHelper.USER_TALBE_NAME);mDb.execSQL("insert into book values(3,'Android');");mDb.execSQL("insert into book values(4,'Ios');");mDb.execSQL("insert into book values(5,'Html5');");mDb.execSQL("insert into user values(1,'jake',1);");mDb.execSQL("insert into user values(2,'jasmine',0);");}//当该表了数据库中的数据后,需要调用mContext.getContentResolver().notifyChange(uri, null);来//通知外界当前ContentProvider中数据已经改变要观察一个ContentProvider中的数据已经发生改变,可以通过ContentResolver的registerContentObserver和
//    unregisterContentObserver来实现注册和解除注册//Provider的增删改查都是在binder的线程池中进行的@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {Log.d(TAG, "query, current thread:" + Thread.currentThread().getName());String table = getTableName(uri);if (table == null) {throw new IllegalArgumentException("Unsupported URI: " + uri);}return mDb.query(table, projection, selection, selectionArgs, null, null, sortOrder, null);}@Overridepublic String getType(Uri uri) {Log.d(TAG, "getType");return null;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;switch (sUriMatcher.match(uri)) {case BOOK_URI_CODE:tableName = DbOpenHelper.BOOK_TABLE_NAME;break;case USER_URI_CODE:tableName = DbOpenHelper.USER_TALBE_NAME;break;default:break;}return tableName;}}

ProviderActivity .java

public class ProviderActivity extends Activity {private static final String TAG = "ProviderActivity";Uri bookUri = Uri.parse("content://com.ryg.chapter_2.book.provider/book");private ContentObserver mObserver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_provider);mObserver = new ContentObserver(new Handler()) {@Overridepublic void onChange(boolean selfChange) {super.onChange(selfChange);System.out.println("观察到BookContentProvider发生改变");}};getContentResolver().registerContentObserver(bookUri, true, mObserver);ContentValues values = new ContentValues();values.put("_id", 6);values.put("name", "程序设计的艺术");//通过对应的uri就可以对ContentProvider进行操作了getContentResolver().insert(bookUri, values);Cursor bookCursor = getContentResolver().query(bookUri, new String[]{"_id", "name"}, null, null, null);while (bookCursor.moveToNext()) {Book book = new Book();book.bookId = bookCursor.getInt(0);book.bookName = bookCursor.getString(1);Log.d(TAG, "query book:" + book.toString());}bookCursor.close();Uri userUri = Uri.parse("content://com.ryg.chapter_2.book.provider/user");Cursor userCursor = getContentResolver().query(userUri, new String[]{"_id", "name", "sex"}, null, null, null);while (userCursor.moveToNext()) {User user = new User();user.userId = userCursor.getInt(0);user.userName = userCursor.getString(1);user.isMale = userCursor.getInt(2) == 1;Log.d(TAG, "query user:" + user.toString());}userCursor.close();}@Overrideprotected void onDestroy() {super.onDestroy();//记得解除观察防止内存泄漏if (mObserver != null) {getContentResolver().unregisterContentObserver(mObserver);mObserver = null;}}
}

代码中有对应注释.

这篇关于ContentProvider解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1006740

相关文章

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

Java MCP 的鉴权深度解析

《JavaMCP的鉴权深度解析》文章介绍JavaMCP鉴权的实现方式,指出客户端可通过queryString、header或env传递鉴权信息,服务器端支持工具单独鉴权、过滤器集中鉴权及启动时鉴权... 目录一、MCP Client 侧(负责传递,比较简单)(1)常见的 mcpServers json 配置

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Java Scanner类解析与实战教程

《JavaScanner类解析与实战教程》JavaScanner类(java.util包)是文本输入解析工具,支持基本类型和字符串读取,基于Readable接口与正则分隔符实现,适用于控制台、文件输... 目录一、核心设计与工作原理1.底层依赖2.解析机制A.核心逻辑基于分隔符(delimiter)和模式匹

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装

深度解析Python yfinance的核心功能和高级用法

《深度解析Pythonyfinance的核心功能和高级用法》yfinance是一个功能强大且易于使用的Python库,用于从YahooFinance获取金融数据,本教程将深入探讨yfinance的核... 目录yfinance 深度解析教程 (python)1. 简介与安装1.1 什么是 yfinance?

99%的人都选错了! 路由器WiFi双频合一还是分开好的专业解析与适用场景探讨

《99%的人都选错了!路由器WiFi双频合一还是分开好的专业解析与适用场景探讨》关于双频路由器的“双频合一”与“分开使用”两种模式,用户往往存在诸多疑问,本文将从多个维度深入探讨这两种模式的优缺点,... 在如今“没有WiFi就等于与世隔绝”的时代,越来越多家庭、办公室都开始配置双频无线路由器。但你有没有注