当前位置: 首页 > news >正文

【Android】进程间如何通信

在这里插入图片描述
三三要成为安卓糕手

一:Content Providers

Content Providers是Android系统提供的一种机制,用于在应用程序之间共享数据(进程间通信的一种)。通过Content Providers,我们可以将数据从一个应用程序传递给另一个应用程序。

二:场景应用

1:需求

假设我们有两个应用:A和B。应用A提供了一个Content Provider来共享它的数据,应用B通过这个Content Provider访问应用A的数据。

第一步先在进程B中完成Sqlite数据库的创建,并插入一些数据,并检查确认数据无误。参考以前的写文章

2:代码

/*** 中介方*/
public class MyContentProvider extends ContentProvider {private MySqliteHelper sqliteHelper;private static final String AUTHORITY = "com.xlong.providerprojecttest.provider";private static final String TABLE_NAME = "user";//初始化contentProvider的时候会被调用//一般会在这里进行数据的初始化,比如说数据库的实例@Overridepublic boolean onCreate() {sqliteHelper = new MySqliteHelper(getContext());if (sqliteHelper == null){return false;}return true;//表示初始化成功}@Nullable@Overridepublic Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {//通过数据库对象进行数据查找,这里的查找条件(参数列表里的参数)是B应用(接收方)提供的SQLiteDatabase database = sqliteHelper.getReadableDatabase();//查询的列,子句,占位符Cursor cursor = database.query(TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);return cursor;}@Nullable@Overridepublic String getType(@NonNull Uri uri) {//返回查询结果的MIME类型String string = "vnd.android.cursor.dir/vnd." + AUTHORITY + "." + TABLE_NAME;return string;}@Nullable@Overridepublic Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {SQLiteDatabase database = sqliteHelper.getWritableDatabase();//返回的是插入的那一行,主键值long id = database.insert(TABLE_NAME, null, values);//content://com.xlong.providerprojecttest.provider/userUri contentUri = Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME);Uri resultUri = ContentUris.withAppendedId(contentUri, id);return resultUri;}@Overridepublic int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {SQLiteDatabase writableDatabase = sqliteHelper.getWritableDatabase();int count = writableDatabase.delete(TABLE_NAME, selection, selectionArgs);//返回受影响的数据有多少条return count;}@Overridepublic int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {SQLiteDatabase database = sqliteHelper.getWritableDatabase();int update = database.update(TABLE_NAME, values, selection, selectionArgs);return update;}
}

三:Provider中重写方法分析

1:表名和授权标识

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • authorityContentProvider 的授权标识(用于唯一确定 ContentProvider),定义格式:包名+.provider

  • table 是对应的数据表名

2:query方法

接收数据的B应用调用中介provider的查询方法,B应用需要传参查询的地址和一些限制条件;

query方法内部进而去数据库中查,把查询结果封装成一个cursor对象返回回去

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • uri:查询的 Content Provider 的资源标识符,指向特定数据集

  • projection:指定要从 Content Provider 中返回的列(字段)

    • 示例String[] projection = {"id", "name"};
  • selection:类似于 SQL 中的WHERE子句,用于指定查询的条件

    • 示例String selection = "name LIKE '%John%'";
  • selectionArgs:用于为selection中的占位符(?)提供具体的值

  • sortOrder:数据的排序方式

3:getType

通过我们的ContentProvider查询到的数据类型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(1)MIME类型格式

Android 为 ContentProvider 定义了特定的 MIME 类型格式,用于区分 “单个数据项” 和 “多个数据项集合”:

  • 多个数据项(集合) :格式为 vnd.android.cursor.dir/vnd.<authority>.<table>

    • vnd.android.cursor.dir:表示这是一个数据集合(多行记录,类似数据库中的表)。
    • vnd.<authority>.<table>:是自定义部分,这样组合能唯一标识该 ContentProvider 下某张表的 “数据集合” 类型。
  • 单个数据项:格式为 vnd.android.cursor.item/vnd.<authority>.<table>,其中 vnd.android.cursor.item 表示这是单个数据项(一行记录)。

(2)作用

当其他组件(如 ContentResolver)通过 Uri 获取 MIME 类型时,就能根据这个格式判断数据是 “集合” 还是 “单个项”,从而进行后续适配的操作(比如集合可能需要列表展示,单个项可能需要详情展示)。

这里是告诉调用者B应用,当前 Uri 对应的是一个数据集合(比如数据库中的整张表,包含多行数据)

(3)类比MediaStore

有异曲同工之处

ContentValues values = new ContentValues();//名字values.put(MediaStore.Images.Media.DISPLAY_NAME,"my_picture.jpeg");//类型values.put(MediaStore.Images.Media.MIME_TYPE,"image/jpeg");//路径values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);

4:insert

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(1)database.insert 返回的 id

插入数据成功后,会返回新插入行的行 ID(这是 SQLite 表中该行的主键值,自增且唯一)

(2)nullColumnHack解释

hack不好翻译

最常见含义:指通过非正统、巧妙甚至略带 “取巧” 的方式解决问题,尤其是绕过常规限制或快速常规流程的解决方案。
Android 中的 nullColumnHack,就体现了这种意味 —— 当插入空数据时,通过指定一个可设为 NULL 的列来 "绕过"SQL 语法限制,是一种为了兼容兼容性或特殊场景设计的取巧机制。

比如,假设我们有一张表,所有列都不允许为空,而我们又想插入一条空数据,如果没有 nullColumnHack 且 ContentValues 为空,INSERT 语句就无法正确构造。有了 nullColumnHack,我们可以指定某一列(比如name列),让其值为 NULL,从而使 INSERT 语句合法。

(3)Uri.parse

把拼接的字符串转化为Uri

(4)ContentUris.withAppendedId(contentUri, id)

contentUri表示一个内容集合的uri

比如 content://authority/table_uesr,指的就是user这个表

追加一个标识具体资源的 ID,指向确定的某一行数据

(5)通信约定

content://${AUTHORITY}/${TABLE_NAME} 这种格式,是 Android 官方推荐的 ContentProvider Uri 规范格式;

本质是一种通信约定“要操作哪个 Provider、哪个表 / 资源”,然后通过 Uri.parse 将这个字符串解析为 Uri 对象,供 ContentResolver 等组件识别和操作。

  • "content://" 是协议头,表明这是 ContentProviderUri(类似于 HTTP 协议的 http://
  • AUTHORITY 是当前 ContentProvider 的授权标识,确保能定位到正确的 ContentProvider
  • TABLE_NAME 作为 path 部分,用于指定要操作的数据表(因为这里是对数据库表进行插入操作,所以用表名作为路径来标识数据所在的 “位置”)。

四:跨进程清单和权限设置

1:数据提供A方

(1)provider声明

        <providerandroid:name=".MyContentProvider"android:authorities="com.xlong.providerprojecttest.provider"android:exported="true"android:grantUriPermissions="true"/>
  • grantUriPermission:授权Uri许可,方便其它的工程通过uri来进行访问

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2:数据使用B方

    <!--在安卓11的设备上需要添加如下声明,表示要访问目标应用中的数据--><queries><package android:name="com.xlong.providerprojecttest"/></queries>

跟权限的声明同级别,允许当前应用去访问一个特定的应用,低版本可以不需要这个声明。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

"com.xlong.providerprojecttest"来自A应用下图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

五:跨进程对数据库进行增删查改

1:查

        /*** 查询数据*/findViewById(R.id.btn_query).setOnClickListener(view -> {Cursor cursor = getContentResolver().query(uri, null, null,null, null);if(cursor != null){while(cursor.moveToNext()){int nameIndex = cursor.getColumnIndexOrThrow("name");String name = cursor.getString(nameIndex);Log.i(TAG, "onCreate: query name = " + name);}}});

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2:增

		/*** 插入数据*/findViewById(R.id.btn_insert).setOnClickListener(view -> {ContentValues values = new ContentValues();values.put("name","sansan");values.put("age",22);Uri insert = getContentResolver().insert(uri, values);Log.i(TAG, "onCreate: 插入了" + insert.toString());});

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3:改

        /*** 更新数据*/findViewById(R.id.btn_update).setOnClickListener(view -> {ContentValues values = new ContentValues();values.put("name","hantianzun");int update = getContentResolver().update(uri, values, "name = ?", new String[]{"zhangsan"});Log.i(TAG, "onCreate: 更新 update =" + update);});

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4:删

        /*** 删除数据*/findViewById(R.id.btn_delete).setOnClickListener(view -> {int delete = getContentResolver().delete(uri, "name = ?", new String[]{"lisi"});Log.i(TAG, "onCreate: delete " + delete);});

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


文章转载自:

http://tjufsfAQ.srLtq.cn
http://61XTOKJs.srLtq.cn
http://lhi8VXqb.srLtq.cn
http://0Qbtr9lj.srLtq.cn
http://dzftCPTi.srLtq.cn
http://WDyw50Al.srLtq.cn
http://QUHQxpOl.srLtq.cn
http://Y8jHgb0n.srLtq.cn
http://pBduaWTr.srLtq.cn
http://dq5TKI7z.srLtq.cn
http://mIFcYvbC.srLtq.cn
http://wtkBE7Qh.srLtq.cn
http://T1ZIJops.srLtq.cn
http://H0GIk23o.srLtq.cn
http://Do8vYNbI.srLtq.cn
http://blzFTrEb.srLtq.cn
http://xYOLpbQ3.srLtq.cn
http://z8S3p95W.srLtq.cn
http://oBX5tguA.srLtq.cn
http://aVvSmTEx.srLtq.cn
http://F4DEUYLS.srLtq.cn
http://MiMlDkhV.srLtq.cn
http://AHPtTQ4C.srLtq.cn
http://JX5FbUff.srLtq.cn
http://52tLV845.srLtq.cn
http://FlqhqRPp.srLtq.cn
http://FcY1lTgL.srLtq.cn
http://GfoUn05o.srLtq.cn
http://DjeCzt9w.srLtq.cn
http://tNfnfwNP.srLtq.cn
http://www.dtcms.com/a/387645.html

相关文章:

  • 从代码源码角度 解读 open-vla 算法架构
  • javaweb Tomcat及运行/HTTP
  • 深入解析 HTTP 状态码
  • PHP 常用函数及用法
  • WordPress 网站邮件通知功能实现指南:以 WP Mail SMTP 插件与 QQ 邮箱为例
  • 【CF】Day144——杂题 (交互 + 思维 | 整除分块)
  • Unity 实验功能实现:天敌捕食猎物(含对象池 + 点击交互)
  • 【docker】——docker国内可用的源
  • React Zustand存储token报错解决方案
  • I/O 多路复用器(select、poll、epoll)与 Reactor 模式详解
  • pytorch自定义算子转tensorrt
  • Springboots上传文件的同时传递参数用对象接收
  • Next.js 中表单处理与校验:React Hook Form 实战
  • 国标GB28181视频平台EasyGBS如何解决安防视频融合与级联管理的核心痛点?
  • Web 页面 SEO 审计自动化 - 基于 n8n 和 Firecrawl
  • arcgis文件导出显示导出对象错误
  • PPT中将图片按比例裁剪
  • React + Zustand 状态管理
  • 复位开关芯片 EY412-A07E50国产低功耗延时芯片方案超低功耗
  • 动态规划-详解回文串系列问题
  • C语言基础学习(五)——进制
  • 如何在C#中将 Excel 文件(XLS/XLSX)转换为 PDF
  • 【Error】django-debug-toolbar不显示:Failed to load module script
  • Windows 版本 WDK 版本 Windows SDK Visual Studio各版本对应关系
  • WPF 快速布局技巧
  • K8S YAML 功能详解:让容器配置更灵活
  • CAD迷你看图下载安装教程(2025最新版)
  • 根据文本区域`textarea`的内容调整大小`field-sizing:content`
  • avcodec_send_packet闪退问题
  • ftrace的trace_marker使用