一、问题描述

  如何在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

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

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

  所有方法均通过了测试,实现了在一个应用(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实现跨进程通讯的更多相关文章

  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()和StartActivityForResult()(图文详解)

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

  7. 初学android:四大组件之contentprovider

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

  8. Android 四大组件之" ContentProvider "

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

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

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

随机推荐

  1. CPU密集型 VS IO密集型

    CPU密集型 CPU密集型也叫计算密集型,指的是系统的硬盘.内存性能相对CPU要好很多,此时,系统运作大部分的状况是CPU Loading 100%,CPU要读/写I/O(硬盘/内存),I/O在很短的 ...

  2. LeetCode(45): 跳跃游戏 II

    Hard! 题目描述: 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 示例: 输入: [ ...

  3. java 延时的几种方法方法

    Java 延时常见的几种方法   1. 用Thread就不会iu无法终止 new Thread(new Runnable() { public void run() { while (true) { ...

  4. python 全栈开发,Day114(装饰器,排序规则,显示列,添加按钮,定制ModelForm,自定义列表页面,自定制URL)

    一.装饰器 装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象. 装饰器的应用场景:比如插入日志,性能测试,事务处理, ...

  5. python 全栈开发,Day11(函数名应用,闭包,装饰器初识,带参数以及带返回值的装饰器)

    一.函数名应用 函数名是什么?函数名是函数的名字,本质:变量,特殊的变量. 函数名(),执行此函数. python 规范写法 1. #后面加一个空格,再写内容,就没有波浪线了. 2.一行代码写完,下面 ...

  6. git merge简介

    git merge的基本用法为把一个分支或或某个commit的修改合并到现在的分支上.我们可以运行git merge -h和git merge --help查看其命令,后者会直接转到一个网页(git的 ...

  7. 多线程中使用CheckForIllegalCrossThreadCalls = false访问窗口

    在多线程程序中,新创建的线程不能访问UI线程创建的窗口控件,如果需要访问窗口中的控件,可以在窗口构造函数中将CheckForIllegalCrossThreadCalls设置为 false publi ...

  8. python ThreadLocal

    ThreadLocal: 主要是为了解决各个线程引用全局变量,并且各个线程之间互不影响而设置的. 实例: import threading threadlocal = threading.local( ...

  9. python全栈开发day21-2 几个装饰器总结

    1 @property 将一个方法伪装成属性 2.@propertty @f.setter 设置伪装成方法的属性 3.@propertty @f.deleter 删除一个伪装成方法的属性. class ...

  10. POJ 1655 Balancing Act (求树的重心)【树形DP】(经典)

    <题目链接> 题目大意:给你一棵树,任意去除某一个点后,树被分成了几个联通块,则该点的平衡值为所有分成的连通块中,点数最大的那个,问你:该树所有点中,平衡值最小的那个点是什么? 解题分析: ...