一、问题描述 |
如何在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实现跨进程通讯的更多相关文章
-
Android四大组件应用系列5——使用AIDL实现跨进程调用Service
一.问题描述 Android应用程序的四大组件中Activity.BroadcastReceiver.ContentProvider.Service都可以进行跨进程.在上一篇我们通过ContentPr ...
-
Android四大组件应用系列——使用BroadcastReceiver和Service实现倒计时
一.问题描述 Service组件可以实现在后台执行一些耗时任务,甚至可以在程序退出的情况下,让Service在后台继续保持运行状态.Service分本地服务和远程服务,Local地服务附在主进程上的m ...
-
Android四大组件应用系列——Activity与Service交互实现APK下载
Servic与Activity相比它没有界面,主要是在后台执行一些任务,Service有两种启动方法startService()和bindService(),startService方式Service ...
-
Android四大组件应用系列——实现电话拦截和电话录音
一.问题描述 使用BordercastReceiver和Service组件实现下述功能: 1.当手机处于来电状态,启动监听服务,对来电进行监听录音. 2.设置电话黑名单,当来电是黑名单电话,则直接挂断 ...
-
Android四大组件之——Activity的生命周期(图文详解)
转载请在文章开头处注明本博客网址:http://www.cnblogs.com/JohnTsai 联系方式:JohnTsai.Work@gmail.com [Andro ...
-
Android四大组件之——Activity的开启:StartActivity()和StartActivityForResult()(图文详解)
如需转载请在文章开头处注明本博客网址:http://www.cnblogs.com/JohnTsai 联系方式:JohnTsai.Work@gmail.com ...
-
初学android:四大组件之contentprovider
一.ContentProvider的概念ContentProvider:为存储和获取数据提供统一的接口.可以在不同的应用程序之间共享数据.Android已经为常见的一些数据提供了默认的ContentP ...
-
Android 四大组件之"; ContentProvider ";
前言 ContentProvider作为Android的四大组件之一,是属于需要掌握的基础知识,可能在我们的应用中,对于Activity和Service这两个组件用的很常见,了解的也很多,但是对Con ...
-
Android四大组件之——ContentProvider(一)
Android四大组件之--ContentProvider(一) 本人邮箱:JohnTsai.Work@gmail.com,欢迎交流讨论. 欢迎转载,转载请注明网址:http://www.cnblog ...
随机推荐
-
mysql 联合索引和唯一索引
一般来说.如果有where a=? and b=? and c=? 的语句. 如果表也有DML, 我一般只在a 上建索引. 这也是代价平衡的结果. 一方面 只在a 上建索引那么是 index ran ...
-
CUDA网格限制
如图
-
iOS与HTML5交互方法总结(转)
今天小编在找技术文章的时候,发现这样一个标题:iOS与HTML5交互方法总结,怎么看着这么熟悉呢? 还以为是刚哥用了别的文章,点进去一看,原来是刚哥自己写的文章,他们转载的,而且还上了Dev St ...
-
【转】分析器窗口 Profiler window
转自unity圣典: http://game.ceeger.com/Manual/ProfilerWindow.html http://game.ceeger.com/Manual/Profiler. ...
-
ansible小结
一.Ansible的安装 1.yum源安装 以centos为例,默认在源里没有ansible,不过在fedora epel源里有ansible,配置完epel 源后,可以直接通过yum 进行安装.这里 ...
-
cocos studio UI 1.6.0.0 修改导出项目路径
因为cocos studio UI 1.6.0.0版本没有自动修改默认导出路径的功能,新建项目后默认导出的路径还是上一个项目的,每次导出都要重新设置路径很麻烦.于是考虑是否可以找到默认配置文件,终于还 ...
-
MySQL主从延迟如何解决?
我们知道生产环境中经常会遇到MySQL主从延迟问题,从原理上也能看出主库的事务提交是并发模式,而从库只有一个SQL线程负责解析,所以本身上就可能存在延迟. 延迟的主要原因在于: 1.从库的配置往往没有 ...
-
WPF编程,获取句柄将外部程序嵌入到WPF界面。
原文:WPF编程,获取句柄将外部程序嵌入到WPF界面. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details ...
-
【代码审计】CmsEasy_v5.7 代码执行漏洞分析
0x00 环境准备 CmsEasy官网:http://www.cmseasy.cn/ 网站源码版本:CmsEasy_v5.7_UTF8-0208 程序源码下载: http://ftp.cmseas ...
-
Executor框架(一)Executor框架介绍
Executor框架简介 Executor框架的两级调度模型 在HotSpot VM的线程模型中,Java线程被一对一映射为本地操作系统线程.Java线程启动时会创建一个本地操作系统线程:当Jav ...