Android四大组件应用系列——使用ContentProvider实现跨进程通讯

时间:2021-08-29 18:24:23
一、问题描述

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

二、应用实现

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

  如图所示:

Android四大组件应用系列——使用ContentProvider实现跨进程通讯

  本例涉及两个应用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

  <provider android:name="com.jereh.PersonProvider"
android:authorities="com.jereh.providers.personprovider">

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);
}
}
}

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

Android四大组件应用系列——使用ContentProvider实现跨进程通讯

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

  AndroidManifest.xml配置:

    <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.jereh.other.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-library android:name="android.test.runner" />
</application>
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.jereh" android:label="My Test">
</instrumentation>
作者:杰瑞教育
出处:http://www.cnblogs.com/jerehedu/ 
版权声明:本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

技术咨询:Android四大组件应用系列——使用ContentProvider实现跨进程通讯
 

Android四大组件应用系列——使用ContentProvider实现跨进程通讯的更多相关文章

  1. Android四大组件应用系列5——使用AIDL实现跨进程调用Service

    一.问题描述 Android应用程序的四大组件中Activity.BroadcastReceiver.ContentProvider.Service都可以进行跨进程.在上一篇我们通过ContentPr ...

  2. Android四大组件应用系列——使用BroadcastReceiver和Service实现倒计时

    一.问题描述 Service组件可以实现在后台执行一些耗时任务,甚至可以在程序退出的情况下,让Service在后台继续保持运行状态.Service分本地服务和远程服务,Local地服务附在主进程上的m ...

  3. Android四大组件应用系列——Activity与Service交互实现APK下载

    Servic与Activity相比它没有界面,主要是在后台执行一些任务,Service有两种启动方法startService()和bindService(),startService方式Service ...

  4. Android四大组件应用系列——实现电话拦截和电话录音

    一.问题描述 使用BordercastReceiver和Service组件实现下述功能: 1.当手机处于来电状态,启动监听服务,对来电进行监听录音. 2.设置电话黑名单,当来电是黑名单电话,则直接挂断 ...

  5. Android四大组件之——Activity的生命周期(图文详解)

        转载请在文章开头处注明本博客网址:http://www.cnblogs.com/JohnTsai       联系方式:JohnTsai.Work@gmail.com       [Andro ...

  6. Android四大组件之——Activity的开启:StartActivity&lpar;&rpar;和StartActivityForResult&lpar;&rpar;(图文详解)

                如需转载请在文章开头处注明本博客网址:http://www.cnblogs.com/JohnTsai       联系方式:JohnTsai.Work@gmail.com   ...

  7. 初学android&colon;四大组件之contentprovider

    一.ContentProvider的概念ContentProvider:为存储和获取数据提供统一的接口.可以在不同的应用程序之间共享数据.Android已经为常见的一些数据提供了默认的ContentP ...

  8. Android 四大组件之&quot&semi; ContentProvider &quot&semi;

    前言 ContentProvider作为Android的四大组件之一,是属于需要掌握的基础知识,可能在我们的应用中,对于Activity和Service这两个组件用的很常见,了解的也很多,但是对Con ...

  9. Android四大组件之——ContentProvider(一)

    Android四大组件之--ContentProvider(一) 本人邮箱:JohnTsai.Work@gmail.com,欢迎交流讨论. 欢迎转载,转载请注明网址:http://www.cnblog ...

随机推荐

  1. mysql 联合索引和唯一索引

    一般来说.如果有where a=? and b=? and c=? 的语句. 如果表也有DML, 我一般只在a 上建索引.  这也是代价平衡的结果. 一方面 只在a 上建索引那么是 index ran ...

  2. CUDA网格限制

    如图

  3. iOS与HTML5交互方法总结(转)

    今天小编在找技术文章的时候,发现这样一个标题:iOS与HTML5交互方法总结,怎么看着这么熟悉呢?   还以为是刚哥用了别的文章,点进去一看,原来是刚哥自己写的文章,他们转载的,而且还上了Dev St ...

  4. 【转】分析器窗口 Profiler window

    转自unity圣典: http://game.ceeger.com/Manual/ProfilerWindow.html http://game.ceeger.com/Manual/Profiler. ...

  5. ansible小结

    一.Ansible的安装 1.yum源安装 以centos为例,默认在源里没有ansible,不过在fedora epel源里有ansible,配置完epel 源后,可以直接通过yum 进行安装.这里 ...

  6. cocos studio UI 1&period;6&period;0&period;0 修改导出项目路径

    因为cocos studio UI 1.6.0.0版本没有自动修改默认导出路径的功能,新建项目后默认导出的路径还是上一个项目的,每次导出都要重新设置路径很麻烦.于是考虑是否可以找到默认配置文件,终于还 ...

  7. MySQL主从延迟如何解决?

    我们知道生产环境中经常会遇到MySQL主从延迟问题,从原理上也能看出主库的事务提交是并发模式,而从库只有一个SQL线程负责解析,所以本身上就可能存在延迟. 延迟的主要原因在于: 1.从库的配置往往没有 ...

  8. WPF编程,获取句柄将外部程序嵌入到WPF界面。

    原文:WPF编程,获取句柄将外部程序嵌入到WPF界面. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details ...

  9. 【代码审计】CmsEasy&lowbar;v5&period;7 代码执行漏洞分析

      0x00 环境准备 CmsEasy官网:http://www.cmseasy.cn/ 网站源码版本:CmsEasy_v5.7_UTF8-0208 程序源码下载: http://ftp.cmseas ...

  10. Executor框架(一)Executor框架介绍

    Executor框架简介 Executor框架的两级调度模型   在HotSpot VM的线程模型中,Java线程被一对一映射为本地操作系统线程.Java线程启动时会创建一个本地操作系统线程:当Jav ...