我为我的应用创建了一个ContentProvider
,供其中的所有进程(而非外部)使用。这是它的外观和用法:
MyProvider.kt
class MyProvider : ContentProvider() {
lateinit var appContext: Context
private lateinit var sharedPreferences: SharedPreferences
private val uriMatcher = UriMatcher(UriMatcher.NO_MATCH).apply {
this.addURI(
AUTHORITY,
URI_IS_FEATURE_ENABLED.pathSegments.joinToString("/"),
URI_CODE_IS_FEATURE_ENABLED
)
}
override fun onCreate(): Boolean {
appContext = context!!.applicationContext
sharedPreferences = appContext.getSharedPreferences(MY_SP_NAME, Context.MODE_PRIVATE)
return true
}
override fun query(
uri: Uri,
projection: Array<String>?,
selection: String?,
selectionArgs: Array<String>?,
sortOrder: String?
): Cursor? {
return when (uriMatcher.match(uri)) {
URI_CODE_IS_FEATURE_ENABLED -> {
createQueryCursorResult(
sharedPreferences.getBoolean(SPK_IS_FEATURE_ENABLED, false)
)
}
else -> {
// this never happens ;)
throw java.lang.IllegalArgumentException("invalid query uri: $uri")
}
}
}
override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<String>?): Int {
// NOT USED :)
return 0
}
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
// NOT USED :)
return 0
}
override fun insert(uri: Uri, values: ContentValues?): Uri? {
// NOT USED :)
return null
}
private fun createQueryCursorResult(value: Boolean): Cursor {
return MatrixCursor(arrayOf(COLUMN_VALUE)).apply {
if (value) {
this.addRow(arrayOf(1))
} else {
this.addRow(arrayOf(0))
}
}
}
companion object {
const val AUTHORITY = "com.my.app.package.example"
const val COLUMN_VALUE = "col_value"
const val MY_SP_NAME = "my_sp_name"
const val SPK_IS_FEATURE_ENABLED = "spk_is_feature_enabled"
val URI_IS_FEATURE_ENABLED = Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(AUTHORITY)
.appendPath("is_feature_enabled")
.build()!!
private const val URI_CODE_IS_FEATURE_ENABLED = 1
}
}
AndroidManifest.xml
<provider
android:authorities="com.my.app.package.my_provider"
android:name=".ContentProviders.MyProvider"
android:process=":my_provider_process"
android:exported="false" />
UsingMyProvider.kt
class UsingMyProvider {
fun query(context: Context): Boolean {
synchronized(this) {
context.contentResolver.query(
MyProvider.URI_IS_FEATURE_ENABLED,
null,
null,
null,
null
)!!.use {
it.moveToFirst()
return it.getInt(it.getColumnIndex(MyProvider.COLUMN_VALUE)) != 0
}
}
}
}
问题是由于某些我不知道的原因,有时context.contentResolver.query(...)
返回null
。它主要发生在三星设备(89%)和Android 6.x(84%)上。观察:我从不向提供者返回null
。
不幸的是,我无法在本地复制它,但是Crashlytics发生了大量崩溃:/。
我的代码有什么问题?我不知道。