zoukankan      html  css  js  c++  java
  • Android IPC机制(四)用ContentProvider进行进程间通信

    前言

    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中也打印出了我们想要的结果,打出了两条游戏信息: 
    这里写图片描述

      

      

  • 相关阅读:
    【POJ3358】Period of an Infinite Binary Expansion-欧拉定理+数论好题
    【POJ3696】The Luckiest Number-欧拉定理+快速幂
    【POJ3090】Visible Lattice Points-欧拉函数应用
    【POJ3090】Visible Lattice Points-欧拉函数应用
    【POJ2891】Strange Way to Express Integers-解一元线性同余方程组
    【POJ2891】Strange Way to Express Integers-解一元线性同余方程组
    【POJ2429】GCD & LCM Inverse-Pollard-rho分解+枚举
    【POJ2429】GCD & LCM Inverse-Pollard-rho分解+枚举
    【POJ1811】Prime Test-Miller-Rabin素数测试+Pollard-rho大数分解
    deleted
  • 原文地址:https://www.cnblogs.com/ganchuanpu/p/9287938.html
Copyright © 2011-2022 走看看