如何从 AppWidgetProvider 调用 ViewModel 函数?

问题描述

我有一个 Retrofit2 API:

interface Api {
    @POST("/my/url")
    suspend fun function()
}

我的 viewmodel 可以调用这个 HTTP 函数

class Mainviewmodel : viewmodel() {

    private val retrofiClient = apiclient.client!!.create(Api::class.java)

    fun test() {
        viewmodelScope.launch {
                retrofitClient.function()
        }
    }
}

当我从我的活动中调用它时没问题。

但我的目标是从我的应用程序的小部件中调用这个 test() 函数。 我的基本 appwidgetprovider 如下所示:

class appwidgetprovider : appwidgetprovider() {

    override fun onUpdate(
        context: Context,appWidgetManager: AppWidgetManager,appWidgetIds: IntArray
    ) {
        // Perform this loop procedure for each App Widget that belongs to this provider
        appWidgetIds.forEach { appWidgetId ->

            val intent = Intent()
            intent.action = "custom-event-name"
            intent.setClassName(
                MainActivity::class.java.getPackage().name,MainActivity::class.java.name
            )

            val pendingIntent = PendingIntent.getbroadcast(
                context.applicationContext,intent,PendingIntent.FLAG_CANCEL_CURRENT
            )
            val views: RemoteViews = RemoteViews(
                context.packageName,R.layout.appwidget
            ).apply {
                setonClickPendingIntent(R.id.test,pendingIntent)
            }

            appWidgetManager.updateAppWidget(appWidgetId,views)
        }
    }
}

主要活动:

class MainActivity : AppCompatActivity() {

    private val receiver: broadcastReceiver = object : broadcastReceiver() {
        override fun onReceive(context: Context?,intent: Intent?) {
            println("INTENT RECEIVED")

        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        registerReceiver(receiver,IntentFilter("custom-event-name"))
        ...
    }

broadcastReceiver 没有接收到意图。即使有,我可以在那里调用我的应用程序功能吗?

如何设置我的应用和/或小部件,以便在我单击小部件中的按钮时调用viewmodel.test() 方法

解决方法

您可以使用 Channel(https://kotlinlang.org/docs/channels.html,对于协程) 或 RxRelay (https://github.com/JakeWharton/RxRelay,对于 rxjava) 而不是使用广播接收器。只需将您的 ChannelRelay 实例放在您的 Application 类中,这样您就可以在您的活动、片段等中访问它。