如何建网站免费/企业如何进行品牌推广

如何建网站免费,企业如何进行品牌推广,狼人在线观看视频人在线,长沙公司做网站多少钱在 Android 开发中,跨应用数据共享是构建开放生态的关键需求。作为四大组件之一,ContentProvider通过标准化接口和安全机制,成为实现这一需求的核心枢纽。本文将围绕其生命周期方法、核心机制、自定义实现及最佳实践展开,帮助开发…

在 Android 开发中,跨应用数据共享是构建开放生态的关键需求。作为四大组件之一,ContentProvider通过标准化接口和安全机制,成为实现这一需求的核心枢纽。本文将围绕其生命周期方法、核心机制、自定义实现及最佳实践展开,帮助开发者全面掌握这一数据共享利器。

一、ContentProvider 的核心定位与生命周期基石

ContentProvider 的设计初衷是打破应用沙箱限制,通过URI暴露数据操作接口,允许其他应用通过 ContentResolver 进行跨进程数据交互。其生命周期与方法实现直接决定了数据共享的稳定性和效率。

二、生命周期方法详解:从初始化到数据交互的全流程

1. onCreate ():初始化的起点
  • 作用:当 ContentProvider 首次被访问时调用,用于执行数据库连接、资源初始化等操作。
  • 实现要点
    • 避免耗时操作,确保快速返回true(返回false表示初始化失败,Provider 不可用)。
    • 典型场景:创建 SQLiteOpenHelper 实例,初始化UriMatcher用于 URI 匹配。
private SQLiteDatabase db;  
private UriMatcher uriMatcher;  @Override  
public boolean onCreate() {  uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);  uriMatcher.addURI("com.example.provider", "users", USERS_DIR);  uriMatcher.addURI("com.example.provider", "users/#", USER_ITEM);  db = new DatabaseHelper(getContext()).getWritableDatabase();  return true;  
}  
2. query ():数据检索的核心逻辑
  • 作用:解析 URI 并执行查询,返回Cursor对象(即使无数据也需返回非空 Cursor,如MatrixCursor)。
  • 参数解析
    • Uri:确定操作目标(单条记录或数据集);
    • projection:指定返回字段,避免全表扫描;
    • selection/selectionArgs:过滤条件,防止 SQL 注入。
  • 返回值规范
@Override  
public Cursor query(Uri uri, String[] projection, String selection,  String[] selectionArgs, String sortOrder) {  switch (uriMatcher.match(uri)) {  case USERS_DIR:  return db.query("users", projection, selection, selectionArgs,  null, null, sortOrder);  case USER_ITEM:  String id = uri.getPathSegments().get(1);  return db.query("users", projection, "_id=?", new String[]{id},  null, null, sortOrder);  default:  throw new IllegalArgumentException("Unknown URI: " + uri);  }  
}  
3. insert ():数据插入与 URI 生成
  • 作用:向 Provider 添加新数据,返回新记录的 URI。
  • 实现要点
    • 使用ContentValues解析键值对,通过SQLiteDatabase.insert()执行插入;
    • 利用ContentUris.withAppendedId()生成包含新记录 ID 的 URI。
@Override  
public Uri insert(Uri uri, ContentValues values) {  long rowId = db.insert("users", null, values);  if (rowId > 0) {  Uri newUri = ContentUris.withAppendedId(USERS_CONTENT_URI, rowId);  getContext().getContentResolver().notifyChange(newUri, null); // 通知数据变更  return newUri;  }  throw new SQLException("Insert failed for URI: " + uri);  
}  
4. update () 与 delete ():数据修改与删除的响应式处理
  • update():根据 URI 和条件更新数据,返回受影响的行数。
@Override  
public int update(Uri uri, ContentValues values, String selection,  String[] selectionArgs) {  int count = 0;  switch (uriMatcher.match(uri)) {  case USERS_DIR:  case USER_ITEM:  count = db.update("users", values, selection, selectionArgs);  break;  }  if (count > 0) {  getContext().getContentResolver().notifyChange(uri, null);  }  return count;  
}  
  • delete():类似逻辑,返回删除的行数,需处理selection为空时的全表删除风险。
5. getType ():URI 到 MIME 类型的映射
  • 作用:返回 URI 对应数据的 MIME 类型,指导 ContentResolver 处理数据格式。
  • 规则
    • 数据集(多条记录):vnd.android.cursor.dir/ + 自定义类型(如vnd.com.example.users);
    • 单条记录:vnd.android.cursor.item/ + 自定义类型。
@Override  
public String getType(Uri uri) {  switch (uriMatcher.match(uri)) {  case USERS_DIR:  return "vnd.android.cursor.dir/vnd.com.example.users";  case USER_ITEM:  return "vnd.android.cursor.item/vnd.com.example.users";  default:  throw new IllegalArgumentException("Unknown URI: " + uri);  }  
}  
6. 高级方法:批量操作与文件访问
  • bulkInsert():批量插入数据,通过循环调用insert()或优化 SQL 语句提升性能,返回成功插入的行数。
  • openFile():提供大文件或媒体数据的访问,返回ParcelFileDescriptor,支持跨进程文件描述符共享(如处理图片、视频等二进制数据)。

三、自定义 ContentProvider 的完整链路

1. 定义 Authority 与数据模型
  • AndroidManifest.xml中注册 Provider,声明唯一的authority(通常为包名)和访问权限:
<provider  android:name=".UserProvider"  android:authorities="com.example.provider"  android:exported="true"  android:readPermission="com.example.permission.READ_USER"  android:writePermission="com.example.permission.WRITE_USER">  
</provider>  

 

2. 实现核心方法与 URI 匹配
  • 使用UriMatcher解析不同 URI 路径,区分数据集(如users)和单条记录(如users/1)。
  • 结合 SQLite 或其他存储方式(如文件、网络)实现数据操作,确保线程安全(避免多线程同时修改数据库)。
3. 客户端访问:通过 ContentResolver 交互

查询数据

Uri uri = Uri.parse("content://com.example.provider/users");  
Cursor cursor = getContentResolver().query(uri, null, null, null, null);  

监听数据变更

getContentResolver().registerContentObserver(uri, true, new ContentObserver(new Handler()) {  @Override  public void onChange(boolean selfChange) {  // 触发UI更新或数据同步  }  
});  

四、数据共享的安全与性能优化

1. 权限控制的三层防护
  • 全局权限:通过android:readPermissionandroid:writePermission限制读写操作。
  • 路径级授权:使用Intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)临时授权特定 URI,避免暴露整个 Provider。
  • 运行时检查:在方法中调用checkCallingPermission(),未授权时抛出SecurityException
2. 性能优化策略
  • 批量操作:利用bulkInsert()减少跨进程通信次数,或通过SQLiteDatabase.beginTransaction()提升数据库操作效率。
  • 投影与索引:在query()中限制返回字段,为常用查询字段添加数据库索引。
  • Cursor 优化:使用MatrixCursor处理空结果,避免返回null;通过CursorWindow调整内存缓冲区大小(默认 1MB)。
3. 跨进程通信原理

ContentProvider 基于Binder 机制实现跨进程通信,数据通过Parcelable序列化或CursorWindow共享内存传输。大文件访问时,openFile()返回的ParcelFileDescriptor通过文件描述符传递,避免内存拷贝。

五、适用场景与最佳实践

  • 系统级数据共享:如读取联系人(ContactsContract)、媒体库(MediaStore),需申请对应权限并处理版本兼容性。
  • 应用内模块化:在组件化项目中,通过 ContentProvider 封装模块数据接口,实现跨模块解耦。
  • 替代方案对比
    • 轻量级数据共享:优先使用SharedPreferences或 Jetpack DataStore;
    • 复杂 IPC 场景:结合 AIDL 实现双向通信,但 ContentProvider 的标准化接口更适合单纯的数据 CRUD。

六、总结:掌握 ContentProvider 的核心本质

ContentProvider 的核心价值在于标准化与安全性:通过统一的生命周期方法和 URI 驱动的操作模型,实现跨应用数据的可控共享。理解其生命周期方法的设计初衷(如onCreate()的初始化职责、query()的非空 Cursor 规范),并结合具体业务场景优化实现(如批量操作、权限控制),是构建健壮数据共享方案的关键。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/73843.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode 通过Remote-ssh远程连接服务器报错 could not establish connection to ubuntu

vscode 通过Remote-ssh插件远程连接服务器报错 could not establish connection to ubuntu&#xff0c;并且出现下面的错误打印&#xff1a; [21:00:57.307] Log Level: 2 [21:00:57.350] SSH Resolver called for "ssh-remoteubuntu", attempt 1 [21:00:57.359] r…

飞书电子表格自建应用

背景 coze官方的插件不支持更多的飞书电子表格操作&#xff0c;因为需要自建应用 飞书创建文件夹 创建应用 开发者后台 - 飞书开放平台 添加机器人 添加权限 创建群 添加刚刚创建的机器人到群里 文件夹邀请群 创建好后&#xff0c;就可以拿到id和key 参考教程&#xff1a; 创…

LangFlow系列:LangFlow快速入门示例

本文介绍了开源AI开发工具LangFlow的快速入门方法。LangFlow作为可视化框架&#xff0c;支持通过拖拽组件构建多智能体及RAG应用&#xff0c;兼容主流大语言模型与向量数据库。文章从环境搭建、核心功能到实战案例逐步讲解&#xff0c;演示如何利用其可视化界面创建智能聊天机器…

基于龙芯3A5000处理器,全国产标准6U VPX板卡解决方案

1&#xff0c;产品功能 本产品为一款高可靠性的基于龙芯3A5000处理器以及 7A2000芯片组的标准6U VPX板卡&#xff0c;具有以太网、SATA、PCIE&#xff0c;以及显示等接口&#xff0c;产品功能框图如图1所示&#xff1a; 图1 系统框图 2&#xff0c;技术指标 序号 项目 指标…

无人机进行航空数据收集对于分析道路状况非常有用-使用无人机勘测高速公路而不阻碍交通-

无人机进行航空数据收集对于分析道路状况非常有用-使用无人机勘测高速公路而不阻碍交通- 瑞士拥有1,400 多公里长的高速公路网络。这些公路将人和货物从山谷高原运送到阿尔卑斯山的最高山口。维护这些高速公路使国家得以顺利运转。高速公路维护的重要性显而易见&#xff0c;但在…

推荐系统(十七):在TensorFlow中用户特征和商品特征是如何Embedding的?

在前面几篇关于推荐模型的文章中&#xff0c;笔者均给出了示例代码&#xff0c;有读者反馈——想知道在 TensorFlow 中用户特征和商品特征是如何 Embedding 的&#xff1f;因此&#xff0c;笔者特意写作此文加以解答。 1. 何为 Embedding &#xff1f; 关于 Embedding&#x…

关于ArcGIS中加载影像数据,符号系统中渲染参数的解析

今天遇到一个很有意思的问题&#xff0c;故记录下来&#xff0c;以作参考和后续的研究。欢迎随时沟通交流。如果表达错误或误导&#xff0c;请各位指正。 正文 当我们拿到一幅成果影像数据的时候&#xff0c;在不同的GIS软件中会有不同效果呈现&#xff0c;但这其实是影像是…

CANoe入门——CANoe的诊断模块,调用CAPL进行uds诊断

目录 一、诊断窗口介绍 二、诊断数据库文件管理 三、添加基础诊断描述文件&#xff08;若没有CDD/ODX/PDX文件&#xff09;并使用对应的诊断功能进行UDS诊断 3.1、添加基础诊断描述文件 3.2、基于基础诊断&#xff0c;使用诊断控制台进行UDS诊断 3.2.1、生成基础诊断 3.…

【数据结构】二叉树的递归

数据结构系列三&#xff1a;二叉树(二) 一、递归的原理 1.全访问 2.主角 3.返回值 4.执等 二、递归的化关系思路 三、递归的方法设计 一、递归的原理 1.全访问 方法里调用方法自己&#xff0c;就会形成调用方法本身的一层一层全新相同的调用&#xff0c;方法的形参设置…

【LVS】负载均衡群集部署(DR模式)

部署前IP分配 DR服务器&#xff1a;192.168.166.101 vip&#xff1a;192.168.166.100 Web服务器1&#xff1a;192.168.166.104 vip&#xff1a;192.168.166.100 Web服务器2&#xff1a;192.168.166.107 vip&#xff1a;192.168.166.100 NFS服务器&#xff1a;192.168.166.108 …

C++Primer学习(14.1 基本概念)

当运算符作用于类类型的运算对象时&#xff0c;可以通过运算符重载重新定义该运算符的含义。明智地使用运算符重载能令我们的程序更易于编写和阅读。举个例子&#xff0c;因为在Sales_item类中定义了输入、输出和加法运算符&#xff0c;所以可以通过下述形式输出两个Sales_item…

计算机视觉准备八股中

一边记录一边看&#xff0c;这段实习跑路之前运行完3DGAN&#xff0c;弄完润了&#xff0c;现在开始记忆八股 1.CLIP模型的主要创新点&#xff1a; 图像和文本两种不同模态数据之间的深度融合、对比学习、自监督学习 2.等效步长是每一步操作步长的乘积 3.卷积层计算输入输出…

基于大语言模型的智能音乐创作系统——从推荐到生成

一、引言&#xff1a;当AI成为音乐创作伙伴 2023年&#xff0c;一款由大语言模型&#xff08;LLM&#xff09;生成的钢琴曲《量子交响曲》在Spotify冲上热搜&#xff0c;引发音乐界震动。传统音乐创作需要数年专业训练&#xff0c;而现代AI技术正在打破这一壁垒。本文提出一种…

VLAN综合实验二

一.实验拓扑&#xff1a; 二.实验需求&#xff1a; 1.内网Ip地址使用172.16.0.0/分配 2.sw1和SW2之间互为备份 3.VRRP/STP/VLAN/Eth-trunk均使用 4.所有Pc均通过DHCP获取IP地址 5.ISP只能配置IP地址 6.所有…

ModuleNotFoundError: No module named ‘ml_logger.logbook‘

问题 (legion) zhouy24RL-DSlab:~/zhouy24Files/legion/LEGION$ python main.py ML_LOGGER_USER is not set. This is required for online usage. Traceback (most recent call last): File “main.py”, line 7, in from mtrl.app.run import run File “/data/zhouy24File…

PyTorch 分布式训练(Distributed Data Parallel, DDP)简介

PyTorch 分布式训练&#xff08;Distributed Data Parallel, DDP&#xff09; 一、DDP 核心概念 torch.nn.parallel.DistributedDataParallel 1. DDP 是什么&#xff1f; Distributed Data Parallel (DDP) 是 PyTorch 提供的分布式训练接口&#xff0c;DistributedDataPara…

【Python】天气数据可视化

1. Python进行数据可视化 在数据分析和科学计算领域&#xff0c;Python凭借其强大的库和简洁的语法&#xff0c;成为了众多开发者和科研人员的首选工具。数据可视化作为数据分析的重要环节&#xff0c;能够帮助我们更直观地理解数据背后的规律和趋势。本文将详细介绍如何使用P…

深度学习4.4笔记

《动手学深度学习》-4.4-笔记 验证数据集&#xff1a;通常是从训练集中划分出来的一部分数据&#xff0c;不要和训练数据混在一起&#xff0c;评估模型好坏的数据集 测试数据集&#xff1a;只用一次的数据集 k-折交叉验证&#xff08;k-Fold Cross-Validation&#xff09;是…

vue 两种路由模式

一、两种模式比较 在vue.js中&#xff0c;路由模式分为两种&#xff1a;hash 模式和 history 模式。这两种模式决定了URL的结构和浏览器历史记录的管理方式。 1. hash 模式带 #&#xff0c;#后面的地址变化不会引起页面的刷新。换句话说&#xff0c;hash模式不会将#后面的地址…

Android生态大变革,谷歌调整开源政策,核心开发不再公开

“开源”这个词曾经是Android的护城河&#xff0c;如今却成了谷歌的烫手山芋。最近谷歌宣布调整Android的开源政策&#xff0c;核心开发将全面转向私有分支。翻译成人话就是&#xff1a;以后Android的核心更新&#xff0c;不再公开共享了。 这操作不就是开源变节吗&#xff0c;…