As we all know, ContentProvider is used for cross-process communication. 他のプロセスがこのプロセスのデータベースで CRUD 操作を実行できるように ContentProvider を継承することで、クエリ、挿入、削除、更新、および getType メソッドを実装できます。大量のデータ このとき、含まれるデータの量が少ない場合は、ContentProvider の call メソッドを書き換えることで、プロセス間通信を簡単に実装できます。
1. ContentProvider を継承し、メソッドを書き換えて、実装する必要があるメソッドを呼び出します。
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/アレックス: 呼び出し (メソッド: onEvent、引数: 文字列?、エクストラ: バンドル?)
ここでは、渡されたメソッド名「onEvent」がすでに表示されており、他のパラメーターをカスタマイズできます。
まぁ、また楽しめます。