IPC机制---04 Android中的IPC通讯方式(E)
来源:互联网 发布:seo常用外链资源整理 编辑:程序博客网 时间:2024/05/16 04:39
- 下面介绍一种IPC通讯的另外一种方式ContentProvider,这是Android中提供的专门用于不同应用间进行数据数据共享的方式。和Messenger一样,底层也是基于Binder的,但是,系统已经为我们做了封装,所以使用起来比AIDL简单多了。
- 系统内置了许多ContentProvider,比如通讯录 短信信息等,要跨进程通信,只需要通过ContentResolver的query update insert和delete方法即可。
- 下面创建一个BookProvider,继承自ContentProvider并实现六个抽象方法即可:
- onCreate 代表CP的创建,一般进行初始化工作,运行在主线程,不建议执行耗时操作
- query 查询记录,运行在CP的进程中,由外界回调并运行在Binder线程池中
- update 更新记录,如上
- insert 添加纪录,如上
- delete 删除记录,如上
- getType 返回一个Uri请求所对应的MIME类型
- 废话不多说,直接上代码
package com.happy.ipc.cp.server;import android.os.Parcel;import android.os.Parcelable;/** * Created by zhonglq on 2016/3/14. */public class Book implements Parcelable { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(this.id); dest.writeString(this.name); } public Book() { } protected Book(Parcel in) { this.id = in.readInt(); this.name = in.readString(); } public static final Creator<Book> CREATOR = new Creator<Book>() { public Book createFromParcel(Parcel source) { return new Book(source); } public Book[] newArray(int size) { return new Book[size]; } };}
package com.happy.ipc.cp.server;import android.os.Parcel;import android.os.Parcelable;/** * Created by zhonglq on 2016/3/14. */public class User implements Parcelable { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(this.id); dest.writeString(this.name); } public User() { } protected User(Parcel in) { this.id = in.readInt(); this.name = in.readString(); } public static final Creator<User> CREATOR = new Creator<User>() { public User createFromParcel(Parcel source) { return new User(source); } public User[] newArray(int size) { return new User[size]; } };}
<pre name="code" class="java">package com.happy.ipc.cp.server;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;/** * Created by zhonglq on 2016/3/14. */public class DBOpenHelper extends SQLiteOpenHelper { private static final String DB_NAME = "demo.db"; private static final int DB_VERSION = 1; public static final String BOOK_TABLE = "book"; public static final String USER_TABLE = "user"; private String CREATE_BOOK_TABLE = "CREATE TABLE IF NOT EXISTS " + BOOK_TABLE + " (" + "_id INTEGER PRIMARY KEY , name TEXT)"; private String CREATE_USER_TABLE = "CREATE TABLE IF NOT EXISTS " + USER_TABLE + " (" + "_id INTEGER PRIMARY KEY , name TEXT)"; public DBOpenHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_BOOK_TABLE); db.execSQL(CREATE_USER_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }}
package com.happy.ipc.cp.server;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;import android.support.annotation.Nullable;/** * Created by zhonglq on 2016/3/14. */public class BookProvider extends ContentProvider { private static final String AUTHORITY = "com.happy.ipc.cp.server.book.provider"; private static final String TAG = "BookProvider"; private SQLiteDatabase mDB; private static final int BOOK_CODE = 1; private static final int USER_CODE = 2; private Context mContext; private static UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { mUriMatcher.addURI(AUTHORITY, "book", BOOK_CODE); mUriMatcher.addURI(AUTHORITY, "user", USER_CODE); } @Override public boolean onCreate() { mContext = getContext(); initDB(); return false; } private void initDB() { mDB = new DBOpenHelper(mContext).getReadableDatabase(); mDB.execSQL("delete from " + DBOpenHelper.BOOK_TABLE); mDB.execSQL("delete from " + DBOpenHelper.USER_TABLE); mDB.execSQL("insert into " + DBOpenHelper.BOOK_TABLE + " values(1,'三国演义') "); mDB.execSQL("insert into " + DBOpenHelper.BOOK_TABLE + " values(2,'红楼梦') "); mDB.execSQL("insert into " + DBOpenHelper.USER_TABLE + " values(1,'旺财') "); mDB.execSQL("insert into " + DBOpenHelper.USER_TABLE + " values(2,'小强') "); } @Nullable @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { String tableName = getTableName(uri); return mDB.query(tableName, projection, selection, selectionArgs, null, null, sortOrder); } @Nullable @Override public String getType(Uri uri) { return null; } @Nullable @Override public Uri insert(Uri uri, ContentValues values) { long insert = mDB.insert(getTableName(uri), null, values); if (insert > 0) { mContext.getContentResolver().notifyChange(uri, null); } return null; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int delete = mDB.delete(getTableName(uri), selection, selectionArgs); if (delete > 0) { mContext.getContentResolver().notifyChange(uri, null); } return delete; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int update = mDB.update(getTableName(uri), values, selection, selectionArgs); if (update > 0) { mContext.getContentResolver().notifyChange(uri, null); } return update; } private String getTableName(Uri uri) { String tableName = null; switch (mUriMatcher.match(uri)) { case BOOK_CODE: tableName = DBOpenHelper.BOOK_TABLE; break; case USER_CODE: tableName = DBOpenHelper.USER_TABLE; break; default: throw new IllegalArgumentException("无法识别的URI"); } return tableName; }}
// 客户端代码package com.happy.ipc.cp.client;import android.database.Cursor;import android.net.Uri;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //以book查询为例 Uri uri = Uri.parse("content://com.happy.ipc.cp.server.book.provider/book"); Cursor cursor = getContentResolver().query(uri, null, null, null, null); if (cursor != null && cursor.getCount() > 0) { while (cursor.moveToNext()) { int id = cursor.getInt(0); String bookName = cursor.getString(1); Log.i(TAG, " id = " + id + " ,bookName = " + bookName); } cursor.close(); } }}
- 注意
- CRUD四个方法是存在多线程并发访问的,因此要做好线程同步
- 本例中,只有一个SQLiteDatabase,所以不会存在什么问题
- SQLiteDatabase内部对数据库的操作时同步处理的,如果多个SQLiteDatebase对象来操作数据库的话,就无法保证线程的同步,因为多个SQLiteDatabase对象之间无法进行线程同步
- 如果ContentProvider的底层数据是一块内存的话,比如List,在这种情况下同List的遍历 插入 删除操作就需要进行线程同步,否则容易引起并发错误
0 0
- IPC机制---04 Android中的IPC通讯方式(E)
- IPC机制---04 Android中的IPC通讯方式(A)
- IPC机制---04 Android中的IPC通讯方式(B)
- IPC机制---04 Android中的IPC通讯方式(C)
- IPC机制---04 Android中的IPC通讯方式(D)
- IPC机制系列之三 Android中的IPC方式
- Android 中的 IPC 机制
- Android中的IPC机制
- android中的IPC机制
- Android中的IPC机制
- Android 中的IPC机制
- Android中的IPC机制
- Android中的IPC机制
- IPC机制系列之三 Android中的IPC方式 (AIDL)
- IPC机制系列之三 Android中的IPC方式 (ContentProvider,Socket)
- Android中进程间通讯(IPC)方式之一AIDL机制
- android 中的IPC方式
- Android中的IPC方式
- 微信 获取 access_token
- [Getting and Cleaning data] Week 2
- 常见的防止过拟合的方法
- Python--for循环
- linux命令
- IPC机制---04 Android中的IPC通讯方式(E)
- ionic如何使用第三方iconfont,以及图标微调 (转载)
- 苹果Macbook Air怎么安装Win7系统图解教程(图)
- java中的集合框架List接口
- Python--while-网络爬虫刷博器
- Python爬虫--捕捉网易首页
- 机器学习模型的评价
- iOS软件检查更新,每次启动检测Appstore是否有更新,每一次更新只提醒一次
- 正则表达式