• Android四大组件应用系列——使用ContentProvider实现跨进程通讯


    一、问题描述

      如何在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/ 
    版权声明:本文版权归杰瑞教育技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    技术咨询:JRedu技术交流
     
  • 相关阅读:
    SDOI2017 树点染色
    ZROI week1
    ZROI week3
    BZOJ 4545
    ZROI week2
    组合数问题
    JSOI2016 独特的树叶
    TJOI2015 组合数学
    Beginning Storyboards in iOS 5 Part 2
    孕妇不能吃的东东
  • 原文地址:https://www.cnblogs.com/jerehedu/p/4891146.html
Copyright © 2020-2023  润新知