ContentResolver.query返回null(即使它从不返回null)

时间:2019-07-26 09:28:00

标签: android nullpointerexception android-contentprovider android-contentresolver

我为我的应用创建了一个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发生了大量崩溃:/。

我的代码有什么问题?我不知道。

0 个答案:

没有答案