basti394
basti394

Reputation: 415

Content Observer onChange takes 10 sec to detect change

I have built to simple Applications:

Application 1 provides and modifies a Content Provider to share a boolean flag via an uri.

Application 2 observers this flag provided by App 1 using a ContentObserver and also can modify the content.

When Application 2 modifies the content, the ContentObservers' onChange method is executed right away. But if Application 1 modifies the content, the onChange method always takes exactly 10 seconds to recognise the change and execute.

Is there a reason why it is always exactly 10 sec and how can I reduce this latency.

Application 1

MyProvider.kt

class MyProvider : ContentProvider() {
    companion object {
        const val AUTHORITY = "pizza.xyz.cp1.provider"

        private const val CODE_DIR = 1
        private val MATCHER = UriMatcher(UriMatcher.NO_MATCH)

        init {
            MATCHER.addURI(
                AUTHORITY,
                "flag",
                CODE_DIR
            )
        }

    }
    val appDatabase: AppDatabase? by lazy {
        context?.let {
            Room.databaseBuilder(
                it,
                AppDatabase::class.java,
                "MyDataBase"
            ).fallbackToDestructiveMigration().build()
        }
    }

    override fun onCreate(): Boolean {
        return true
    }

    override fun insert(
        uri: Uri,
        values: ContentValues?
    ): Uri {
        return when (MATCHER.match(uri)) {
            CODE_DIR -> {
                println("Writing flag in cp1: ${values?.getAsBoolean("flag")} ")
                appDatabase?.flagDao()?.updateFlag(values?.getAsBoolean("flag") ?: false)
                context?.contentResolver?.notifyChange(uri, null)
                uri
            }
            else -> throw java.lang.IllegalArgumentException("Unknown URI: $uri")
        }
    }

    @Nullable
    override fun query(
        uri: Uri,
        @Nullable projection: Array<String>?,
        @Nullable selection: String?,
        @Nullable selectionArgs: Array<String>?,
        @Nullable sortOrder: String?
    ): Cursor? {
        return when (MATCHER.match(uri)) {
            CODE_DIR -> {
                val context = context ?: return null
                val cursor: Cursor? = appDatabase?.flagDao()?.fetchFlag()
                cursor?.setNotificationUri(context.contentResolver, uri)
                cursor
            }
            else -> throw IllegalArgumentException("Unknown URI: $uri")
        }
    }
}

AndroidManifest

<provider
    android:authorities="pizza.xyz.cp1.provider"
    android:name=".MyProvider"
    android:exported="true"
    android:enabled="true"
    android:multiprocess="true"
    android:readPermission="pizza.xyz.PERMISSION"
    android:writePermission="pizza.xyz.PERMISSION"/>

Application 2

ContentObserverFlow.kt

class ContentObserverFlow(private val contentResolver: ContentResolver, private val uri: Uri) : ContentObserver(
    Handler(Looper.getMainLooper())
) {
    private val _flow = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
    val flow: Flow<Unit> get() = _flow

    init {
        contentResolver.registerContentObserver(uri, true, this)
    }

    override fun onChange(selfChange: Boolean) {
        println("change detected cp2")
        _flow.tryEmit(Unit)
    }

    fun unregister() {
        contentResolver.unregisterContentObserver(this)
    }
}

AndroidManifest

<uses-permission android:name="pizza.xyz.PERMISSION"/>

<queries>
    <package android:name="pizza.xyz.cp1.provider"/>
</queries>

Upvotes: 1

Views: 130

Answers (0)

Related Questions