首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将只在运行时已知的参数注入到Android工作人员中?

如何将只在运行时已知的参数注入到Android工作人员中?
EN

Stack Overflow用户
提问于 2022-11-14 22:06:34
回答 1查看 34关注 0票数 1

目标

如何将myObjectmyClass参数传递给下面的GlanceWorker

背景

我正在使用android-workmanager运行后台任务。这些任务是从我用一瞥添加的主屏幕小部件初始化的。正如Google 这里所建议的(请参阅“如何获取数据?”)我使用工作人员来更新从ActionCallback启动的Glance。

要更新我的小部件,工作构造函数需要有两个额外的参数myObjectmyClass (除了contextworkerParameters)。到目前为止,我所读到的所有例子都提到了使用WorkerFactory来实现这一点。这个额外的参数总是在启动时提供给工厂或通过匕首图注入。

但是,在我的例子中,这些额外参数的类型取决于创建ActionCallback的小部件(每个小部件都有自己的GlanceStateDefinition()GlanceAppWidget()扩展)。因此,我只能在运行时向工作人员提供额外的参数(据我所知),并且不知道如何将其预先提供给自定义WorkerFactory。为了使它更加复杂,我的一个额外参数使用了一个通用的T

代码语言:javascript
复制
abstract class Action<T : ShowPortfolioMenuState<T>>(
    val myObject: GlanceStateDefinition<T>,
    val myClass: Class<out WidgetAbstractClass>,
) : ActionCallback {

    override suspend fun onAction(
        context: Context,
        glanceId: GlanceId,
        parameters: ActionParameters,
    ) {
        val glanceIdInt = GlanceAppWidgetManager(context).getAppWidgetId(glanceId)
        val showMenu = parameters[ActionParameters.Key("showMenu")] ?: false

        val glanceWork =
            OneTimeWorkRequest.Builder(GlanceWorkerPortfolioChange::class.java)
                .setInputData(
                    workDataOf("GLANCE_ID" to glanceIdInt, "SHOW_MENU" to showMenu)
                ).build()

        WorkManager.getInstance(context)
            .beginUniqueWork("Worker Name",
                ExistingWorkPolicy.REPLACE,
                glanceWork
            ).enqueue()
    }
}
代码语言:javascript
复制
@HiltWorker
class GlanceWorker<T: ShowMenuState<T>> @AssistedInject constructor(
    @Assisted val context: Context,
    @Assisted workerParameters: WorkerParameters,
    val myObject: GlanceStateDefinition<T>, /*<--- how do i add to constructor*/
    val myClass: Class<out WidgetAbstractClass>, /*<--- how do i add to constructor*/
    ): CoroutineWorker(context, workerParameters) {
    
    override suspend fun doWork(): Result {
        val glanceIdInt = inputData.getInt("GLANCE_ID", -1)
        val glanceId = GlanceAppWidgetManager(context).getGlanceIdBy(glanceIdInt)
        val showMenu = inputData.getBoolean("SHOW_MENU", false)

        myClass.apply {
            updateAppWidgetState(context, myObject, glanceId) { state -> /*state is of type T*/
                state.updateShowMenu(showMenu)
            }
            update(context, glanceId)
        }
        return Result.success()
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-15 09:20:08

几件事:

  1. 行动不能采取参数。一目了然不能实例化类并失败。相反:
    1. 使用ActionParameters将类名作为字符串传递,然后使用Class.forName(..)获取类型/实例。
    2. 使用GlanceAppWidget实例获取状态https://developer.android.com/reference/kotlin/androidx/glance/appwidget/GlanceAppWidget#(androidx.glance.appwidget.GlanceAppWidget).getAppWidgetState(android.content.Context,androidx.glance.GlanceId)

  2. 您可以通过将它作为workData传递给工作人员,从而对它进行同样的操作。

一些工人的例子:

https://github.com/android/user-interface-samples/blob/main/AppWidget/app/src/main/java/com/example/android/appwidget/glance/weather/WeatherWorker.kt

https://github.com/android/user-interface-samples/blob/main/AppWidget/app/src/main/java/com/example/android/appwidget/glance/image/ImageWorker.kt

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74438401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档