前言

ContentProvider为存储和获取数据提供统一的接口,它可以在不同的应用程序之间共享数据,本身就是适合进程间通信的。ContentProvider底层实现也是Binder,但是使用起来比AIDL要容易许多。系统也预制了很多的ContentProvider,例如通讯录,音视频等,这些操作本身就是跨进程进行通信。这篇文章主要是我们来自己实现用ContentProvider来进行进程间通信,而非介绍ContentProvider怎么使用。

1. 建立数据库,方便ContentProvider使用

我们创建数据库,并创建表”game_provider.db”,里面有两个字段分别存储游戏的名字和游戏的描述。(DbOpenHelper.java)

public class DbOpenHelper extends SQLiteOpenHelper {
private static final String DB_NAME="game_provider.db";
static final String GAME_TABLE_NAME="game";
private static final int DB_VERSION=1;
private String CREATE_GAME_TABLE="create table if not exists " + GAME_TABLE_NAME +"(_id integer primary key," + "name TEXT, "+"describe TEXT)"; public DbOpenHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
} @Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_GAME_TABLE);
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }
}

2. 使用ContentProvider对数据库进行操作

在initProvoder方法中,我们开启线程来对数据库进行操作,删除表的所有数据,再添加数据,并实现了query和insert方法。(GameProvider.java)

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri; public class GameProvider extends ContentProvider {
public static final String AUTHORITY = "com.example.liuwangshu.mooncontentprovide.GameProvider";
public static final Uri GAME_CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/game");
private static final UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private SQLiteDatabase mDb;
private Context mContext;
private String table; static {
mUriMatcher.addURI(AUTHORITY, "game", 0);
} @Override
public boolean onCreate() {
table = DbOpenHelper.GAME_TABLE_NAME;
mContext = getContext();
initProvoder();
return false;
} private void initProvoder() {
mDb = new DbOpenHelper(mContext).getWritableDatabase();
new Thread(new Runnable() {
@Override
public void run() {
mDb.execSQL("delete from " + DbOpenHelper.GAME_TABLE_NAME);
mDb.execSQL("insert into game values(1,'九阴真经ol','最好玩的武侠网游');");
}
}).start();
} @Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
String table = DbOpenHelper.GAME_TABLE_NAME;
Cursor mCursor = mDb.query(table, projection, selection, selectionArgs, null, sortOrder, null);
return mCursor;
} @Override
public String getType(Uri uri) {
return null;
} @Override
public Uri insert(Uri uri, ContentValues values) {
mDb.insert(table, null, values);
mContext.getContentResolver().notifyChange(uri, null);
return null;
} @Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
} @Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return 0;
}
}

在manifest文件中,我们要让ContentProvider运行在另一个进程

<provider
android:authorities="com.example.liuwangshu.mooncontentprovide.GameProvider"
android:name=".GameProvider"
android:process=":provider"
></provider>

3. 在Activity中调用另一个进程的GameProvider的方法

在Activity中我们在GameProvider再插入一条数据(此前GameProvider初始化时已经插入了一条数据),然后调用GameProvider的query方法来查询数据库中有几条数据并打印出来。

import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log; public class ContentProviderActivity extends AppCompatActivity {
private final static String TAG = "ContentProviderActivity"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content_provider);
Uri uri = Uri.parse("content://com.example.liuwangshu.mooncontentprovide.GameProvider");
ContentValues mContentValues = new ContentValues();
mContentValues.put("_id", 2);
mContentValues.put("name", "大航海时代ol");
mContentValues.put("describe", "最好玩的航海网游");
getContentResolver().insert(uri, mContentValues);
Cursor gameCursor = getContentResolver().query(uri, new String[]{"name", "describe"}, null, null, null);
while (gameCursor.moveToNext()) {
Game mGame = new Game(gameCursor.getString(0), gameCursor.getString(1));
Log.i(TAG, mGame.gameName + "---" + mGame.gameDescribe);
}
}
}

Game.java

public class Game implements Parcelable {
public String gameName;
public String gameDescribe; public Game(String gameName, String gameDescribe) {
this.gameName = gameName;
this.gameDescribe = gameDescribe;
} protected Game(Parcel in) {
gameName = in.readString();
gameDescribe = in.readString();
} public static final Creator<Game> CREATOR = new Creator<Game>() {
@Override
public Game createFromParcel(Parcel in) {
return new Game(in);
} @Override
public Game[] newArray(int size) {
return new Game[size];
}
}; @Override
public int describeContents() {
return 0;
} @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(gameName);
dest.writeString(gameDescribe);
}
}

我们运行程序,发现GameProvider运行在另一个进程 

log中也打印出了我们想要的结果,打出了两条游戏信息: 

  

  

Android IPC机制(四)用ContentProvider进行进程间通信的更多相关文章

  1. Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用

    在上一篇文章Android IPC机制(二)用Messenger进行进程间通信中我们介绍了使用Messenger来进行进程间通信的方法.可是我们能发现Messenger是以串行的方式来处理client ...

  2. Android IPC机制全解析<一>

    概要 多进程概念及多进程常见注意事项 IPC基础:Android序列化和Binder 跨进程常见的几种通信方式:Bundle通过Intent传递数据,文件共享,ContentProvider,基于Bi ...

  3. 深入理解Android IPC机制之Binder机制

    Binder是Android系统进程间通信(IPC)方式之一.Linux已经拥有的进程间通信IPC手段包括(Internet Process Connection): 管道(Pipe).信号(Sign ...

  4. Android IPC机制基础

    概要 多进程概念及多进程常见注意事项 IPC基础:Android序列化和Binder 跨进程常见的几种通信方式:Bundle通过Intent传递数据,文件共享,ContentProvider,基于Bi ...

  5. Android IPC机制—Binder的工作机制

    进程和线程的关系 IPC机制即为跨进程通信,是inter-Process Communication的缩写.是指两个进程之间进行通信.在说进程通信之前,我们的弄明白什么是线程,什么是进程.进程和线程是 ...

  6. android IPC 机制 (开发艺术探索)

    一.IPC 机制介绍 IPC是Inter-Process Communication的缩写,含义就是进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程.那么什么是进程,什么是线程,进程和线程 ...

  7. Android IPC机制之ContentProvider

    ContentProvider:即内容提供者,用来管理数据,并对外暴露一个uri,外部可以通过uri和数据建立联系并获取或操作数据: 服务端:1.首先创建一个数据库类,并创建一个表:2.创建一个Con ...

  8. Android IPC机制(二)用Messenger进行进程间通信

    Messenger可以在不同进程中传递Message对象,我们在Message中加入我们想要传的数据就可以在进程间的进行数据传递了.Messenger是一种轻量级的IPC方案并对AIDL 进行了封装, ...

  9. Android IPC机制之AIDL

    什么是AIDL AIDL:Android Interface Definition Language,即Android接口定义语言. Android系统中的进程之间不能共享内存,因此,需要提供一些机制 ...

随机推荐

  1. 召回率,精确率,mAP如何计算

    首先用训练好的模型得到所有测试样本的confidence  score,每一类(如car)的confidence   score保存到一个文件中(如comp1_cls_test_car.txt).假设 ...

  2. python常用库函数 - 备忘

    基础库 1. 正则表达式:re 符号 ()小括号 -- 分组 []中括号 -- 字符类,匹配所包含的任一字符 #注:字符集合把[]里面的内容当作普通字符!(-\^除外) {}大括号 -- 限定匹配次数 ...

  3. springBoot(2)---快速创建项目,初解jackson

    快速创建项目,初解jackson 一.快速创建项目 springboot官网提供了工具类自动创建web应用:网址:http://start.spring.io/ 官网页面 1.快速创建一个 选择web ...

  4. sql server 性能调优之 逻辑内存消耗最大资源分析1 (自sqlserver服务启动以后)

    一.概述 IO 内存是sql server最重要的资源,数据从磁盘加载到内存,再从内存中缓存,输出到应用端,在sql server 内存初探中有介绍.在明白了sqlserver内存原理后,就能更好的分 ...

  5. FIleZilla连接linux(Ubuntu)服务器的相关问题

    想通过FileZilla传个tomcat到服务器,然后遇到了下面的两个问题,问题已经通过百度解决了,这里总结下: 1,虚拟机通过桥接模式连网,ip地址为:192.168.119.147 在FieZil ...

  6. 项目ITP(四) javaweb http json 交互 in action (服务端 spring 手机端 提供各种工具类)勿喷!

    前言 系列文章:[传送门] 洗了个澡,准备写篇博客.然后看书了.时间 3 7 分.我慢慢规律生活,向目标靠近.  很喜欢珍惜时间像叮当猫一样 正文 慢慢地,二维码实现签到将要落幕了.下篇文章出二维码实 ...

  7. nohup & expect & netstat学习

    1.nohup 用途:不挂断地运行命令,通常加上‘&’命令,& 放在命令后面表示设置此进程为后台进程.分为两种情况,如下: 在不使用密码的情况下使用nohup,只需按如下形式即可: n ...

  8. 这一年多来,阿里Blink测试体系如何从0走向成熟?

    引言 Apache Flink是面向数据流处理和批处理的分布式开源计算框架,2016年阿里巴巴引入Flink框架,改造为Blink.2017年,阿里整合了所有流计算产品,决定以Blink引擎为基础,打 ...

  9. Build a Machine Learning Portfolio(构建机器学习投资组合)

    Complete Small Focused Projects and Demonstrate Your Skills (完成小型针对性机器学习项目,证明你的能力) A portfolio is ty ...

  10. CPU上下文切换

    CPU上下文切换包括进程上下文切换.线程上下文切换及中断上下文切换,当任务进行io或发生时间片事件及发生中断(如硬件读取完成)时,就会进入内核态,发生CPU上下文切换. 进程上下文切换,进程的上下文信 ...