参考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)
网友评论