android ContentProvider call方法的使用

总所周知,ContentProvider用于跨进程通信,可以通过继承ContentProvider实现query、insert、delete、update、getType方法,来让其他进程对本进程的数据库进行CRUD增删改查操作,一般这是涉及到数据大的时候,如果涉及的数据量很小,可以通过重写ContentProvider的call 方法来简单实现跨进程通信;

1、继承ContentProvider,重写必须实现的方法和call方法:

package com.example.myapplication

import android.content.ContentProvider
import android.content.ContentValues
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import android.util.Log

class MyContentProvider: ContentProvider() {

    override fun onCreate(): Boolean {
        return true
    }

    override fun query(
        p0: Uri,
        p1: Array<out String>?,
        p2: String?,
        p3: Array<out String>?,
        p4: String?
    ): Cursor? {
        return null

    }

    override fun getType(p0: Uri): String? {
        return null
    }

    override fun insert(p0: Uri, p1: ContentValues?): Uri? {
        return null
    }

    override fun delete(p0: Uri, p1: String?, p2: Array<out String>?): Int {
        return 0
    }

    override fun update(p0: Uri, p1: ContentValues?, p2: String?, p3: Array<out String>?): Int {
        return 0
    }

    override fun call(method: String, arg: String?, extras: Bundle?): Bundle? {
        Log.d("Alex", "call(method: $method, arg: String?, extras: Bundle?)")
        return super.call(method, arg, extras)
    }

    override fun call(authority: String, method: String, arg: String?, extras: Bundle?): Bundle? {
        Log.d("Alex", "call(authority: String, method: $method, arg: String?, extras: Bundle?)")
        return super.call(authority, method, arg, extras)
    }
}
<provider
            android:name=".MyContentProvider"
            android:authorities="com.example.myapplication.MyContentProvider"
            android:exported="true"/>

2、模拟一个其他进程,比如服务进程:

package com.example.myapplication

import android.app.Service
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.IBinder
import androidx.annotation.RequiresApi

class Myservice: Service() {

    companion object {
        const val URI: String = "content://com.example.myapplication.MyContentProvider/"
    }

    @RequiresApi(Build.VERSION_CODES.Q)
    override fun onCreate() {
        super.onCreate()
        // contentResolver通过Context实例可以拿到
        contentResolver.call(Uri.parse(URI), "onEvent", "", null)
    }

    override fun onBind(p0: Intent?): IBinder? {
        TODO("Not yet implemented")
    }
}
        <service
            android:name=".Myservice"
            android:process=":myservice"></service>

3、找个地方开启这个服务进程:

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
        // TODO: Use the ViewModel
        activity?.startService(Intent(activity, Myservice::class.java))

    }

4、打印结果,表明已经实现了跨进程通信,服务进程已经调用了ContentProvider的call方法:

2022-12-25 12:15:47.685 10970-18681/com.example.myapplication D/Alex: call(authority: String, method: onEvent, arg: String?, extras: Bundle?)
2022-12-25 12:15:47.685 10970-18681/com.example.myapplication D/Alex: call(method: onEvent, arg: String?, extras: Bundle?)

这里已经能看到传过来的method方法名“onEvent” , 其他参数都可以自定义哈。

好了,又可以愉快玩耍了。

猜你喜欢

转载自blog.csdn.net/msn465780/article/details/128434269