美文网首页
IPC之ContentProvider

IPC之ContentProvider

作者: 钦_79f7 | 来源:发表于2019-12-17 12:41 被阅读0次

    参考Android开发艺术探索

    Provider 服务端

    class BookProvider : ContentProvider() {
        companion object {
            const val TAG = "BookProvider"
            const val AUTHORITY = "${BuildConfig.APPLICATION_ID}.book_provider"
    
            val USER_CONTENT_URI: Uri = Uri.parse("content://$AUTHORITY/user")
            val BOOK_CONTENT_URI: Uri = Uri.parse("content://$AUTHORITY/book")
    
            const val BOOK_URI_CODE = 0
            const val USER_URI_CODE = 1
        }
    
        private val sUriMatcher = UriMatcher(UriMatcher.NO_MATCH)
        private lateinit var mDb: SQLiteDatabase
    
        init {
            //创建URI关联,可以进入SDK中查看注释使用示例
            //这里将 book 和 user 两个表分别与URICode进行了关联,分别为 0 和 1
            sUriMatcher.addURI(AUTHORITY, "book", BOOK_URI_CODE)
            sUriMatcher.addURI(AUTHORITY, "user", USER_URI_CODE)
        }
    
        private fun getTableName(uri: Uri): String {
            return when (sUriMatcher.match(uri)) {
                BOOK_URI_CODE -> DbOpenHelper.BOOK_TABLE_NAME
                USER_URI_CODE -> DbOpenHelper.USER_TABLE_NAME
                else -> ""
            }
        }
    
    
        override fun onCreate(): Boolean {
            Logs.d(TAG, "onCreate, current thread is : ${Thread.currentThread().name}")
            initProviderData()
            return true
        }
    
        /**
         * 初始化数据库,执行数据库操作属于耗时操作
         */
        private fun initProviderData() {
            println("provider init data")
            mDb = DbOpenHelper(context).writableDatabase
            mDb.execSQL("delete from ${DbOpenHelper.BOOK_TABLE_NAME}")
            mDb.execSQL("delete from ${DbOpenHelper.USER_TABLE_NAME}")
            mDb.execSQL("insert into book values(3,'Android');")
            mDb.execSQL("insert into book values(4,'iOS');")
            mDb.execSQL("insert into book values(5,'Html5');")
            mDb.execSQL("insert into user values(1,'jake',1);")
            mDb.execSQL("insert into user values(2,'jasmine',0);")
        }
    
        override fun insert(uri: Uri, values: ContentValues?): Uri {
            Logs.d(TAG, "insert, current thread is : ${Thread.currentThread().name}")
            val tableName = getTableName(uri)
            if (tableName.isEmpty()) {
                throw IllegalArgumentException("Unsupported URI: $uri")
            }
            mDb.insert(tableName, null, values)
            context.contentResolver.notifyChange(uri, null)
            return uri
        }
    
        override fun query(uri: Uri, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor? {
            Logs.d(TAG, "query, current thread is : ${Thread.currentThread().name}")
            val tableName = getTableName(uri)
            if (tableName.isEmpty()) {
                throw IllegalArgumentException("Unsupported URI : $uri")
            }
            return mDb.query(tableName, projection, selection, selectionArgs, null, null, sortOrder, null)
        }
    
    
        override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<out String>?): Int {
            val row = mDb.update(getTableName(uri), values, selection, selectionArgs)
            if (row > 0) {
                context.contentResolver.notifyChange(uri, null)
            }
            return row
        }
    
        override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?): Int {
            val count = mDb.delete(getTableName(uri), selection, selectionArgs)
            if (count > 0) {
                context.contentResolver.notifyChange(uri, null)
            }
            return count
        }
    
        override fun getType(uri: Uri?): String? {
            Logs.d(TAG, "getType, current thread is : ${Thread.currentThread().name}")
            return null
        }
    }
    

    客户端

    class ProviderActivity : AppCompatActivity() {
        companion object {
            const val TAG = "ProviderActivity"
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_provider)
            setTitle(R.string.title_content_provider)
    
            executeSQL()
        }
    
        private fun executeSQL() {
            val values = ContentValues()
            values.put("_id", 6)
            values.put("name", "程序设计艺术")
            contentResolver.insert(BookProvider.BOOK_CONTENT_URI, values)
            val bookCursor = contentResolver.query(BookProvider.BOOK_CONTENT_URI, arrayOf("_id", "name"), null, null, null)
            while (bookCursor.moveToNext()) {
                Logs.d(TAG, "query book: ${Book(bookCursor.getInt(0), bookCursor.getString(1))}")
            }
            bookCursor.close()
    
            val userCursor = contentResolver.query(BookProvider.USER_CONTENT_URI, arrayOf("_id", "name", "sex"), null, null, null)
            while (userCursor.moveToNext()) {
                Logs.d(TAG, "query user : ${User(userCursor.getInt(0), userCursor.getString(1), userCursor.getInt(2))}")
            }
            userCursor.close()
        }
    }
    

    数据库辅助类

    class DbOpenHelper(context: Context) : SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) {
        companion object {
            const val DB_VERSION = 1
            const val DB_NAME = "book_provider.db"
            const val BOOK_TABLE_NAME = "book"
            const val USER_TABLE_NAME = "user"
    
            //图书和用户信息表
            const val CREATE_BOOK_TABLE = "CREATE TABLE IF NOT EXISTS $BOOK_TABLE_NAME(_id INTEGER PRIMARY KEY,name TEXT)"
            const val CREATE_USER_TABLE = "CREATE TABLE IF NOT EXISTS $USER_TABLE_NAME(_id INTEGER PRIMARY KEY,name TEXT,sex INT)"
        }
    
        override fun onCreate(db: SQLiteDatabase) {
            db.execSQL(CREATE_BOOK_TABLE)
            db.execSQL(CREATE_USER_TABLE)
        }
    
        override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
            TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        }
    }
    

    AndroidManifets

            <!-- 关于权限的声明,还可以分为读权限与写权限,外界应用在访问此provider的时候必须依次声明相应的读写权限,否则外界应用会异常终止 -->
            <provider
                android:name=".demo.provider.BookProvider"
                android:authorities="${applicationId}.book_provider"
                android:permission="com.qxb.PROVIDER"
                android:process=":provider" />
            <activity android:name=".demo.provider.ProviderActivity" />
    

    运行结果

    com.stone.testdemo:provider D/BookProvider: [ main: (BookProvider.kt:48) onCreate ] - onCreate, current thread is : main
    com.stone.testdemo:provider I/System.out: provider init data
    com.stone.testdemo:provider D/BookProvider: [ Binder_2: (BookProvider.kt:69) insert ] - insert, current thread is : Binder_2
    com.stone.testdemo:provider D/BookProvider: [ Binder_1: (BookProvider.kt:80) query ] - query, current thread is : Binder_1
    com.stone.testdemo D/ProviderActivity: [ main: (ProviderActivity.kt:31) executeSQL ] - query book: Book(id=3, name=Android)
    t:31) executeSQL ] - query book: Book(id=4, name=iOS)
    com.stone.testdemo D/ProviderActivity: [ main: (ProviderActivity.kt:31) executeSQL ] - query book: Book(id=5, name=Html5)
    t:31) executeSQL ] - query book: Book(id=6, name=程序设计艺术)
    com.stone.testdemo:provider D/BookProvider: [ Binder_2: (BookProvider.kt:80) query ] - query, current thread is : Binder_2
    com.stone.testdemo D/ProviderActivity: [ main: (ProviderActivity.kt:37) executeSQL ] - query user : User(id=1, name=jake, sex=1)
    t:37) executeSQL ] - query user : User(id=2, name=jasmine, sex=0)
    

    相关文章

      网友评论

          本文标题:IPC之ContentProvider

          本文链接:https://www.haomeiwen.com/subject/sussnctx.html