Android IPC通信ContentProvider基本实现

一、ContentProvider介绍

    ContentProvider的底层是Binder,主要用于跨进程访问。

    通过实现ContentProvider的query、update、insert、delete等方法即可。

二、ContentProvider创建


三、权限设置

    创建时,需要在AndroidMainfest中声明权限 authorities为唯一标识。

    

<provider
            android:name=".MyContentProvider"
            android:authorities="com.example.fyq.broadtest"  //这是唯一标识,一般写包名
            android:permission="com.example.PROVIDER" //这是权限,需要有此权限才可以访问
            android:process=":provider"//开启另一进程
            android:enabled="true"
            android:exported="true"></provider>

四、实现应用访问

    同一应用的其他进程或者另一应用来访问结果是一样的,实现如下:

public class ProviderActivity extends Activity {
    /**
     * 外部访问类,用于访问ContentProvider及数据库
     * @param savedInstanceState
     */

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_provider);
        Uri uri = Uri.parse("com.example.fyq.broadtest");//android:authorities属性的标识
        getContentResolver().query(uri, null, null, null, null);
        getContentResolver().query(uri, null, null, null, null);
        getContentResolver().query(uri, null, null, null, null);

        //======================添加内容
        /**
         * 访问book表
         */
        Uri bookUri = Uri.parse("content://com.example.fyq.broadtest/book");
        
        ContentValues values = new ContentValues();
        values.put("_id", 6);
        values.put("name", "书名");
        getContentResolver().insert(bookUri, values);//插入一本书
        //查询所有书
        Cursor bookCursor = getContentResolver().query(bookUri, new String[]{"_id", "name"}, null, null, null);
        while (bookCursor.moveToNext()) {
            Book book = new Book();
            book.bookId = bookCursor.getInt(0);
            book.bookName = bookCursor.getString(1);
        }
        bookCursor.close();
        //======================添加内容
    }
}

五、创建数据库及表的类

/**
 * Created by fyq on 2018/5/17.
 * 这个类是创建数据库的类
 */

public class DbOpenHelper extends SQLiteOpenHelper {

    private static final String DB_NAME = "book_provider.db";//数据库名
    public static final String BOOK_TABLE_NAME = "book";
    public static final String USER_TABLE_NAME = "user";
    private static final int DB_VERSION = 1;

    //执行语句   ----PRIMARY主键
    private String CREATE_BOOK_TABLE = "CREATE TABLE IF NOT EXISTS" + BOOK_TABLE_NAME + "(_id INTEGER PRIMARY KEY," + "name TEXT";
    private String CREATE_USER_TABLE = "CREATE TABLE IF NOT EXISTS" + USER_TABLE_NAME + "(_id INTEGER PRIMARY KEY," + "name TEXT," + "sex INT)";


    public DbOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    public DbOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version,
                        DatabaseErrorHandler errorHandler) {
        super(context, name, factory, version, errorHandler);
    }

    public DbOpenHelper(Context mContext) {
        super(mContext, 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) {

    }
}

六、数据库操作类

/**
 * 这个类是用于访问数据库,对数据库进行操作的
 */
public class BookContentProvider extends ContentProvider {
    private static final String TAG = "BookContentProvider";
    //==============二、添加内容====================
    /**
     *用于对应Uri和Uri_Code
     */
    public static final String AUTHORITY = "com.example.fyq.broadtest";//这个是根据AndroidMainfest中唯一标识来命名的
    //对Book和User两个不同的对象定义URI的标识
    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;

    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    static {
        sUriMatcher.addURI(AUTHORITY, "book", BOOK_URI_CODE);//通过此方式关联Uri和Uri_Code
        sUriMatcher.addURI(AUTHORITY, "user", USER_URI_CODE);
    }

    private SQLiteDatabase mDb;
    private Context mContext;

    /**
     * 通过Uri获取Uri_Code,根据Uri_Code再得到表名
     */
    private String getTableName(Uri uri) {
        String tableName = null;
        switch (sUriMatcher.match(uri)) {
            case BOOK_URI_CODE://知道Code后获取表名
                tableName = DbOpenHelper.BOOK_TABLE_NAME;
                break;
            case USER_URI_CODE:
                tableName = DbOpenHelper.USER_TABLE_NAME;
                break;
            default:
                break;
        }
        return tableName;
    }
    //===============二、添加内容==================


    public BookContentProvider() {
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public boolean onCreate() {
        mContext = getContext();
        initProviderData();//ContentProvider创建时初始化数据库。此过程不应在主线程中进行,因为耗时
        return true;
    }

    private void initProviderData() {
        mDb = new DbOpenHelper(mContext).getWritableDatabase();//DBOpen是继承自SQLiteOpenHelper的
        /**
         * 之后mDb.execSQL执行SQL语句
         */
    }

    /**
     * 除了query外,其他三个方法会引起数据源改变
     * @param uri
     * @param projection
     * @param selection
     * @param selectionArgs
     * @param sortOrder
     * @return
     */
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        Log.d(TAG, "query: current thread:" + Thread.currentThread().getName());

        String table = getTableName(uri);
        if (table == null) {
            // TODO: Implement this to handle query requests from clients.
            throw new UnsupportedOperationException("Not yet implemented");
        }
        return mDb.query(table, projection, selection, selectionArgs, null, null, sortOrder, null);

    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        String table = getTableName(uri);
        if(table == null) {
            // TODO: Implement this to handle requests to insert a new row.
            throw new UnsupportedOperationException("Not yet implemented");
        }
        mDb.insert(table, null, values);
        //可能通过ContentProvider的registerContentObserver来注册观察者;通过unre...来解绑
        mContext.getContentResolver().notifyChange(uri,null);//通知外界数据有变化
        return uri;

    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        /**
         * ignore未写
         */
        // TODO: Implement this to handle requests to update one or more rows.
        throw new UnsupportedOperationException("Not yet implemented");
    }
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        /**
         * ignore未写
         */
        // Implement this to handle requests to delete one or more rows.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}


猜你喜欢

转载自blog.csdn.net/fyq520521/article/details/80312014
今日推荐