IPC机制--利用ContentProvider

本例Git地址:https://github.com/NoClay/MessagerTest.git

为什么使用ContentProvider?

ContentProvider是Android中提供的专门用于不同应用间进行数据共享的方式,从这点来看,它天生就是为了进程间通信的,和Messenger一样,ContentProvider的底层实现同样是Binder。

怎样使用ContentProvider?

自定义ContentProvider需要实现以下几个方法:

方法名含义
onCreate创建ContentProvider,初始化工作
getType返回一个Uri请求所对应的MIME类型,比如照片,视频等,可以直接在方法中返回null或者*/*
query查找
update更新
insert插入
delete删除

对于ContentProvider数据存储的实现,我们可以选择使用文件,内存中的对象,也可以使用SQLite实现。

1. 实现SQLite

package com.example.no_clay.messagertest.Item255;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * Created by no_clay on 2017/2/28.
 */

public class DBOpenHelper extends SQLiteOpenHelper {

    public static final String DB_NAME = "book_provider.db";
    public static final String BOOK_TABLE_NAME = "book";
    public static final String USER_TABLE_NAME = "user";
    public static final int DB_VERSION = 1;
    public static final String CREATE_BOOK_TABLE = "create table if not exists " +
            BOOK_TABLE_NAME + " (id text primary key, name text)";
    public static final String CREATE_USER_TABLE = "create table if not exists " +
            USER_TABLE_NAME + " (id text primary key, name text)";

    public DBOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, 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) {

    }
}

2. 实现自定义的ContentProvider

package com.example.no_clay.messagertest.Item255;

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;
import android.util.Log;

import com.example.no_clay.messagertest.Util.MyConstants;

/**
 * Created by no_clay on 2017/2/28.
 */

public class BookProvider extends ContentProvider {
    private static final String TAG = "BookProvider";
    public static final String AUTHORITY = MyConstants.PACKAGE_NAME + ".BookProvider";
    public static final Uri BOOK_CONTENT_URI = Uri.parse("content://" + AUTHORITY
            + "/book");
    public static final Uri USER_CONTENT_URI = Uri.parse("content://" + AUTHORITY
            + "/user");
    public static final int BOOK_URI_CODE = 0;
    public static final int USER_URI_CODE = 1;
    public static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
    public Context mContext;
    private SQLiteDatabase mDatabase;


    static {
        URI_MATCHER.addURI(AUTHORITY, "book", BOOK_URI_CODE);
        URI_MATCHER.addURI(AUTHORITY, "user", USER_URI_CODE);
    }

    private String getTableName(Uri uri){
        String tableName = null;
        switch (URI_MATCHER.match(uri)){
            case 0:tableName = DBOpenHelper.BOOK_TABLE_NAME;
                break;
            case 1:tableName = DBOpenHelper.USER_TABLE_NAME;
                break;
            default:break;
        }
        return tableName;
    }

    @Override
    public boolean onCreate() {
        Log.d(TAG, "onCreate: thread = " + Thread.currentThread().getName());
        mContext = getContext();
        mDatabase = new DBOpenHelper(mContext,
                DBOpenHelper.DB_NAME,
                null,
                DBOpenHelper.DB_VERSION).getWritableDatabase();
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                initData();
//            }
//        }).start();
        return false;
    }

//    private void initData() {
//        mDatabase.execSQL("insert into book values('num012', 'Android')");
//        ContentValues value = new ContentValues();
//        value.put("id", "num014");
//        value.put("name", "Java编程思想");
//        mDatabase.insert(DBOpenHelper.BOOK_TABLE_NAME, null, value);
//        value.clear();
//        value.put("id", "num016");
//        value.put("name", "Android开发艺术探索");
//        mDatabase.insert(DBOpenHelper.BOOK_TABLE_NAME, null, value);
//        value.clear();
//        value.put("id", "04141087");
//        value.put("name", "高XX");
//        mDatabase.insert(DBOpenHelper.USER_TABLE_NAME, null, value);
//        value.clear();
//        value.put("id", "04141085");
//        value.put("name", "莫X");
//        mDatabase.insert(DBOpenHelper.USER_TABLE_NAME, null, value);
//        value.clear();
//        value.put("id", "04141086");
//        value.put("name", "张XX");
//        mDatabase.insert(DBOpenHelper.USER_TABLE_NAME, null, value);
//
//    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        Log.d(TAG, "query: thread = " + Thread.currentThread().getName());
        String table = getTableName(uri);
        if (table == null){
            throw new IllegalArgumentException("不支持的URI");
        }
        return mDatabase.query(table, projection, selection, selectionArgs,
                null, null, sortOrder, null);
    }

    @Nullable
    @Override
    public String getType(Uri uri) {
        Log.d(TAG, "getType: thread = " + Thread.currentThread().getName());
        return null;
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        Log.d(TAG, "insert: thread = " + Thread.currentThread().getName());
        Log.d(TAG, "insert: uri = " + uri);
        String table = getTableName(uri);
        if (table == null){
            throw new IllegalArgumentException("不支持的URI");
        }
        mDatabase.insert(table, null, values);
        mContext.getContentResolver().notifyChange(uri, null);
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        Log.d(TAG, "delete: thread = " + Thread.currentThread().getName());
        String table = getTableName(uri);
        if (table == null){
            throw new IllegalArgumentException("不支持的URI");
        }
        int count = mDatabase.delete(table, selection, selectionArgs);
        if (count > 0){
            getContext().getContentResolver().notifyChange(uri, null);
        }
        return count;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        Log.d(TAG, "update: thread = " + Thread.currentThread().getName());
        String table = getTableName(uri);
        if (table == null){
            throw new IllegalArgumentException("不支持的URI");
        }
        int row = mDatabase.update(table, values, selection, selectionArgs);
        if (row > 0){
            getContext().getContentResolver().notifyChange(uri, null);
        }
        return 0;
    }
}

3. 注册ContentProvider组件

        <provider
            android:name=".Item255.BookProvider"
            android:authorities="com.example.no_clay.messagertest.BookProvider"
            android:permission="com.example.no_clay.messagertest.PROVIDER"
            android:process=":provider"/>

注意:
ContentProvider的onCreate方法由系统进行回调并运行在主线程方法中,而其他五个方法由外界回调并运行在Binder线程池中,这一点结果如下验证了:

03-01 15:45:41.168 12129-12129/com.example.no_clay.messagertest:provider D/BookProvider: onCreate: thread = main
03-01 15:45:41.176 12129-12146/com.example.no_clay.messagertest:provider D/BookProvider: query: thread = Binder_2
03-01 15:45:41.183 11082-11082/com.example.no_clay.messagertest D/BookProviderActivity: onCreate: book name = 程序设计的艺术
03-01 15:45:41.183 11082-11082/com.example.no_clay.messagertest D/BookProviderActivity: onCreate: book name = Android
03-01 15:45:41.183 11082-11082/com.example.no_clay.messagertest D/BookProviderActivity: onCreate: book name = Java编程思想
03-01 15:45:41.183 11082-11082/com.example.no_clay.messagertest D/BookProviderActivity: onCreate: book name = Android开发艺术探索
03-01 15:45:41.183 11082-11082/com.example.no_clay.messagertest D/BookProviderActivity: onCreate: book name = 程序设计的艺术
03-01 15:45:41.185 12129-12146/com.example.no_clay.messagertest:provider D/BookProvider: query: thread = Binder_2
03-01 15:45:41.187 11082-11082/com.example.no_clay.messagertest D/BookProviderActivity: query user:com.example.no_clay.messagertest.Data.User@42ca9ed8
03-01 15:45:41.187 11082-11082/com.example.no_clay.messagertest D/BookProviderActivity: query user:com.example.no_clay.messagertest.Data.User@42caa308
03-01 15:45:41.188 11082-11082/com.example.no_clay.messagertest D/BookProviderActivity: query user:com.example.no_clay.messagertest.Data.User@42caa658

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值