美文网首页
ContentPrivider跨应用获取数据

ContentPrivider跨应用获取数据

作者: 小城哇哇 | 来源:发表于2022-11-14 15:55 被阅读0次

1.背景

最近公司有一个新的业务功能,需要在我们的系统的主APP里面获取到其它所有APP的播放历史记录,在接到这个需求的时候,跨进程获取第三方应用数据的方法有很多种,IPC、广播、ContentPrivider(基于AIDL),但是获取数据是所有的播放记录,所有第一选择就是ContentPrivider.

我们一般使用ContentPrivider都是用来读取第三方的数据库信息,返回的是一个Cursor,因为各个业务线的数据格式都是不一样的,必须让各个业务线返回相同的数据字段便于统一处理,开始是考虑封装一个SDK给其他各个业务,把播放记录都存放到我们统一封装的数据库表,这样做的弊端有以下两点:

  1. 这样的弊端就是第三方的业务要保存一份自己的数据库信息,同时还要单独在我们的SDK里面进行数据存储
  2. 应用之前已有的历史数据都要在第一次使用的时候导入到新的数据库
  3. 只能读取数据库的数据,应用获取数据不一定在本地可能在后台需要去后台读取数据

2.实现方案

为了解决上述两个弊端,在无意中看到了MatrixCursor 这个类,通过这个类可以构造一个虚拟的Cursor,即使没有数据库也能通过ContentPrivider共享数据给第三方的应用。

还是需要定义一个ContentPrivider,如下:

<pre data-language="plain" id="2YABp" class="ne-codeblock language-plain" style="border: 1px solid #e8e8e8; border-radius: 2px; background: #f9f9f9; padding: 16px; font-size: 13px; color: #595959">public class MyProvider extends ContentProvider {

    // 以下是ContentProvider的6个方法

    /**
     * 初始化ContentProvider
     */
    @Override
    public boolean onCreate() {
        return true;
    }

    /**
     * 添加数据
     */

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
        // 该方法在最下面
        return uri;
    }

    /**
     * 查询数据
     */
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        String[] tableCursor = new String[]{"name", "job", "salary"};
            MatrixCursor matrixCursor = new MatrixCursor(tableCursor);
           matrixCursor.addRow(new Object[]{"张三", "老司机", "11111"});
            matrixCursor.addRow(new Object[]{"李四", "维修员", "2222"});
            matrixCursor.addRow(new Object[]{"王五", "开发工程师", "3333"});
            return matrixCursor; 
    }

    /**
     * 更新数据
     */
    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        // 由于不展示,此处不作展开
        return 0;
    }

    /**
     * 删除数据
     */
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // 由于不展示,此处不作展开
        return 0;
    }

    @Override
    public String getType(Uri uri) {
        // 由于不展示,此处不作展开
        return null;
    }

}</pre>

重点看一下这个query方法:

<pre data-language="plain" id="5N6qr" class="ne-codeblock language-plain" style="border: 1px solid #e8e8e8; border-radius: 2px; background: #f9f9f9; padding: 16px; font-size: 13px; color: #595959"> /**
     * 查询数据
     */
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
            String[] tableCursor = new String[]{"name", "job", "salary"};
            MatrixCursor matrixCursor = new MatrixCursor(tableCursor);
            matrixCursor.addRow(new Object[]{"张三", "老司机", "11111"});
            matrixCursor.addRow(new Object[]{"李四", "维修员", "2222"});
            matrixCursor.addRow(new Object[]{"王五", "开发工程师", "3333"});
            return matrixCursor; 
    }
</pre>

首先我们实例化一个MatrixCursor,传入表字段,然后通过addRow方法一次根据添加数据后返回即可;

然后把MyPrivider定义到AndroidManifest.xml文件

<pre data-language="plain" id="Rgc29" class="ne-codeblock language-plain" style="border: 1px solid #e8e8e8; border-radius: 2px; background: #f9f9f9; padding: 16px; font-size: 13px; color: #595959">  <provider
            android:name="com.data.dataprovider.MyProvider"
            android:authorities="${applicationId}.myprovider"
            android:exported="true" /></pre>

当每个业务apk集成这个MyProvider后,我们主APP就可以直接去获取数据了

然后在系统主APP里面正常调用ContentPrivider数据一样即可:

<pre data-language="plain" id="XdLl4" class="ne-codeblock language-plain" style="border: 1px solid #e8e8e8; border-radius: 2px; background: #f9f9f9; padding: 16px; font-size: 13px; color: #595959">  // 设置URI
   Uri uri_user = Uri.parse("content://scut.carson_ho.contentprovider.myprovider");
   ContentResolver resolver = getContentResolver();
        //可以传入参数,进行分页查询等
   Cursor cursor = resolver.query(uri_user, new String[]{"page", "size","data"}, "data", new String[]{"1","10  0","123"}, null);

 while (cursor.moveToNext()) {
   Log.d("MatrixCursor", "query:" +"  name:"+ cursor.getString(0) + "  job:" + cursor.getString(1) + "  salary:"  + cursor.getString(2));

                    // 将表中数据全部输出
 }
    cursor.close();
//打印结果
D/MatrixCursor: query:  name:张三  job:老司机  salary:11111
D/MatrixCursor: query:  name:李四  job:维修员  salary:2222
D/MatrixCursor: query:  name:王五  job:开发工程师  salary:3333</pre>

后续不管各个业务的数据从本地数据库还是从后台获取,都能够通过统一的字段返回,主APP不用考虑数据问题。

来自:https://www.yuque.com/u435816/omigec/kggwiu

相关文章

  • ContentPrivider跨应用获取数据

    1.背景 最近公司有一个新的业务功能,需要在我们的系统的主APP里面获取到其它所有APP的播放历史记录,在接到这个...

  • 利用window.name+iframe跨域获取数据详解

    利用window.name+iframe跨域获取数据详解

  • Android跨应用获取资源

    跨应用获取资源有两种方式 方式一 利用PackageManager 方式二 利用目标资源所在的Context 备注...

  • 实现跨域的方法

    不同域下的接口获取数据,可以使用jsonp和cors。(ie10以下可以使用jsonp获取数据) jsonp实现跨...

  • 如何学习

    【What】获取信息 【Why】提取信息,总结规律 【How】应用 跨界学习,降维打击

  • jsop跨域获取数据

    想着试试用jsonp跨域获取数据看看,原理看了很多次了,利用新建script标签设置src属性最后追加到body中...

  • Jquery跨域获取数据

    接入 PM2.5 数据 数据来源 接入方式 使用 Jquery ,直接请求数据,使用 jsonp 完成Ajax的跨...

  • 又连接器玩上瘾了

    连接器将互联网上的多种应用连接起来,使之“联动”起来,跨平台实现数据交互。 在物联网逐渐普及的今天,这种能跨应用跨...

  • 大数据建设意见

    结合当前大数据建设现状 一、数据获取 二、数据治理 三、数据应用 四、数据分析

  • 隐私条款

    本应用不会获取贩卖你的任何数据

网友评论

      本文标题:ContentPrivider跨应用获取数据

      本文链接:https://www.haomeiwen.com/subject/utljxdtx.html