博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android四大组件应用系列——使用ContentProvider实现跨进程通讯
阅读量:5927 次
发布时间:2019-06-19

本文共 7978 字,大约阅读时间需要 26 分钟。

一、问题描述

  如何在Android中实现不同应用之间的通讯(既跨进程进行调用)?Android提供了多种实现方式,使我们可以实现跨进程访问Activity、通过ContentProvider跨进程访问其他应用的数据、通过Broadcast可以向android系统中所有应用程序发送广播、使用AIDL实现跨进程的Service。下面我们就使用ContentProvider实现跨进程访问数据,并可对数据进行增、删、改、查

二、应用实现

  使用ContentProvider实现数据共享,主要是共享应用的Sqlite数据库,再一个应用中(本例的shareinfo)提供数据源(Sqlite数据库)并创建ContentProvider组件, ContentProvider组件主要对外(其他应用)提供访问数据的接口(Uri信息),其他应用(本例的other)通过这个接口(Uri信息)实现跨进程的方法调用

  如图所示:

   本例涉及两个应用shareinfo和other

三、shareinfo应用的核心

  作为数据的提供者首先是开发对外可访问的数据库(Sqlite)

  涉及两个组件DbOpenHelper和SQLiteHelper

  代码如下:

public class DbOpenHelper extends SQLiteOpenHelper {    public DbOpenHelper(Context context) {        super(context, "jereh.db", null, 4);    }    @Override    public void onCreate(SQLiteDatabase db) {        db.execSQL("create table person(personid integer primary key " +                " autoincrement,name varchar(20),phone varchar(12) null)");    }    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){        db.execSQL("drop table person");        onCreate(db);    }}public class SQLiteHelper {    private Context context;    private DbOpenHelper  helper = null;    public SQLiteHelper(Context context){        helper = new DbOpenHelper(context);    }        public void save(Person person){
//增 SQLiteDatabase db = helper.getWritableDatabase(); db.execSQL("insert into person(name,phone) values(?,?)",new Object[]{person.getName(),person.getPhone()}); db.close(); } public void delete(int personid){
//删 SQLiteDatabase db = helper.getWritableDatabase(); db.execSQL("delete from person where personid=?", new Integer[]{personid}); db.close(); } public void update(Person person){
//改 SQLiteDatabase db = helper.getWritableDatabase(); db.execSQL("update person set name=?,phone=? where personid=?", new Object[]{person.getName(),person.getPhone(),person.getPersonid()}); db.close(); } public Person find(int personid){
//查 SQLiteDatabase db = helper.getReadableDatabase(); //Cursor cursor = db.rawQuery("select * from person where personid=?", new String[]{personid+""}); Cursor cursor=db.rawQuery("select * from person",null); if(cursor.moveToFirst()){ int id = cursor.getInt(cursor.getColumnIndex("personid")); String name = cursor.getString(cursor.getColumnIndex("name")); String phone = cursor.getString(cursor.getColumnIndex("phone")); return new Person(personid, name, phone); } cursor.close(); return null; } }

然后编写ContentProvider组件代码如下:

package com.jereh;public class PersonProvider extends ContentProvider {    private DbOpenHelper openHelper;    private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);    private static final int PERSONS = 1;    private static final int PERSON = 2;    static{        MATCHER.addURI("com.jereh.providers.personprovider", "person", PERSONS);            //* 根据pesonid来删除记录        MATCHER.addURI("com.jereh.providers.personprovider", "person/#", PERSON);    }    @Override    public boolean onCreate() {        openHelper = new DbOpenHelper(this.getContext());        return false;    }    @Override    public Cursor query(Uri uri, String[] projection, String selection,            String[] selectionArgs, String sortOrder) {        SQLiteDatabase sqLiteDatabase = openHelper.getReadableDatabase();        switch (MATCHER.match(uri)) {        case 1:            return sqLiteDatabase.query("person", projection, selection, selectionArgs, null, null, sortOrder);        case 2:            long rowid = ContentUris.parseId(uri);            String where = "personid="+rowid;            if(selection != null && "".equals(selection.trim())){                where = selection+"and"+where;            }            return sqLiteDatabase.query("person", projection, where, selectionArgs, null, null, sortOrder);        }        return null;    }    @Override    public String getType(Uri uri) {        switch (MATCHER.match(uri)) {        case 1:            return "vnd.android.cursor.dir/person";        case 2:            return "vnd.android.cursor.item/person";        }        return null;    }    @Override    public Uri insert(Uri uri, ContentValues values) {        SQLiteDatabase sqLiteDatabase = openHelper.getWritableDatabase();        switch (MATCHER.match(uri)) {        case 1:            long rowid = sqLiteDatabase.insert("person", "name", values);            return ContentUris.withAppendedId(uri, rowid);        default:            break;        }        return null;    }    //* 删除特定personid行的记录    @Override    public int delete(Uri uri, String selection, String[] selectionArgs) {        SQLiteDatabase sqLiteDatabase = openHelper.getWritableDatabase();        switch (MATCHER.match(uri)) {        case 1:            return sqLiteDatabase.delete("person", selection, selectionArgs);        case 2:            long rowid = ContentUris.parseId(uri);            String where = "personid="+rowid;            if(selection != null && "".equals(selection.trim())){                where = selection+"and"+where;            }            return sqLiteDatabase.delete("person", where, selectionArgs);        }        return 0;    }    @Override    public int update(Uri uri, ContentValues values, String selection,            String[] selectionArgs) {        SQLiteDatabase sqLiteDatabase = openHelper.getWritableDatabase();        switch (MATCHER.match(uri)) {        case 1:            return sqLiteDatabase.update("person", values, selection, selectionArgs);        case 2:            long rowid = ContentUris.parseId(uri);            String where = "personid="+rowid;            if(selection != null && "".equals(selection.trim())){                where = selection+"and"+where;            }            return sqLiteDatabase.update("person", values, where, selectionArgs);        }        return 0;    }}

在AndroidManifest.xml中注册provider

shareinfo应用编写完成

四、编写other应用

  接下来编写other应用,在这个应用中访问shareinfo中数据,我们使用Android JUnit进行测试,开发单元测试组件如下:

public class AccessProvider extends AndroidTestCase {    public void testInsert(){        Uri uri = Uri.parse("content://com.jereh.providers.personprovider/person");        ContentResolver resolver = this.getContext().getContentResolver();        ContentValues values = new ContentValues();        values.put("name", "xiaoli");        values.put("phone", "333333");        resolver.insert(uri, values);    }        public void testDelete(){        Uri uri = Uri.parse("content://com.jereh.providers.personprovider/person/2");        ContentResolver resolver = this.getContext().getContentResolver();        resolver.delete(uri, null, null);    }    public void testUpdate(){        Uri uri = Uri.parse("content://com.jereh.providers.personprovider/person/3");        ContentResolver resolver = this.getContext().getContentResolver();        ContentValues values = new ContentValues();        values.put("name", "ljb");        values.put("phone", "00000000");        resolver.update(uri, values, null, null);    }        public void testQuery(){        Uri uri = Uri.parse("content://com.jereh.providers.personprovider/person");        ContentResolver resolver = this.getContext().getContentResolver();        Cursor cursor = resolver.query(uri, new String[]{"name","phone"}, null, null, null);        while(cursor.moveToNext()){            String name = cursor.getString(cursor.getColumnIndex("name"));            String phone = cursor.getString(cursor.getColumnIndex("phone"));            System.out.println("name="+name+" "+"phone="+phone);        }    }}

执行单元测试,测试结果如图所示:

 

  所有方法均通过了测试,实现了在一个应用(other)中访问另一个应用(shareinfo)中的数据

  AndroidManifest.xml配置:

 

作者:杰瑞教育
出处:
 
版权声明:本文版权归
技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
技术咨询:
 
你可能感兴趣的文章
荐书|Python编程之美:最佳实践指南,带你了解编程的美丽
查看>>
米6将取消3.5mm耳机插口,你还买吗?
查看>>
Rust Cargo使用总结
查看>>
【重温基础】9.正则表达式
查看>>
动态语言与鸭子类型
查看>>
爬虫入门系列(一):快速理解 HTTP 协议
查看>>
教你编写一个机器学习代码也能使用的单元测试
查看>>
vue组件之间的数据传递
查看>>
提高 webpack 构建 Vue 项目的速度
查看>>
聊聊Dubbo(二):简单入门
查看>>
远程控制你的智能电视,按键|输入|安装App等都已实现,已开源!
查看>>
springboot 获取项目版本号
查看>>
[译] Flutter 实用指南:给初学者的 6 个小帖士
查看>>
当使用js修改value值时,vue的值如何更新
查看>>
参加第一届宇宙 JavaScript 大会是怎样的体验?
查看>>
iOS 生命周期的缺失和错乱
查看>>
图表太丑怎么破,ECharts神器带你飞!
查看>>
我反编译了Java 10的本地变量类型推断
查看>>
jother编码之谜
查看>>
Java多线程-带你认识Java内存模型,内存分区,从原理剖析Volatile关键字
查看>>