我正在嘗試創建一個基類GenericAction來處理 Glance 小部件更新。它需要兩個引數:一個物件GlanceStateDefinition和一個類GlanceAppWidget(),因為每個小部件將具有不同的狀態定義和要更新的廣播接收器。這被分別稱為
updateAppWidgetState和updateStart。
我已遵循此處提供的指導并獲得了以下代碼。
我面臨兩個問題:
updateAppWidgetState()我得到的 lambda 中的編譯錯誤error - Unresolved reference: copy。我相信這是因為編譯器不知道如何推斷泛型型別T。- 實體化時出現運行時錯誤
glanceWidget。Error in Glance App Widget java.lang.NoSuchMethodException: com.example.myproject.WidgetSymbolClass.<init> [class android.content.Context].WidgetSymbolClass()我相信android由于某種原因找不到我的 GlanceAppWidget 的建構式。
如果有人知道如何擺脫這些錯誤并修復以下代碼,我將不勝感激GenericAction()。
abstract class GenericAction<T>(val myObject: GlanceStateDefinition<T>, val myClass: Class<out WidgetSymbolClass>) : ActionCallback {
override suspend fun onAction(context: Context, glanceId: GlanceId, parameters: ActionParameters) {
val index = parameters.get(ActionParameters.Key<Int>("IndexParam")) ?: 0
val portfolioId = parameters.get(ActionParameters.Key<String>("PortfolioId")) ?: "Portfolio 1"
val showPortfolioMenu = parameters.get(ActionParameters.Key<Boolean>("showMenu")) ?: false
updateAppWidgetState(context, myObject, glanceId) { state ->
state.copy(
/*error - Unresolved reference: copy*/
/*error - Type mismatch. Required: T Found: Unit*/
showPortfolioMenu = showPortfolioMenu,
)
}
val glanceWidget = myClass.getConstructor(Context::class.java).newInstance(context) /*error java.lang.NoSuchMethodException WidgetSymbolClass.<init>*/
glanceWidget.updateStart( glanceId = glanceId, portfolioId = portfolioId, index = index)
}
}
class WidgetSymbolShowMenu: GenericAction<WidgetSymbolState>(WidgetSymbolStateDefinition, WidgetSymbolClass::class.java)
class WidgetSymbolClass @JvmOverloads constructor() : WidgetAbstractClass()
abstract class WidgetAbstractClass (): GlanceAppWidget() {
fun updateStart(
glanceId: GlanceId?,
appWidgetId: Int? = null,
index: Int = 0,
portfolioId: String = "Portfolio 1"
) {
/*start updating widget*/
}
}
/*myObect1 - T is WidgetSymbolState*/
object StateDefinitionSymbol: GlanceStateDefinition<WidgetSymbolState> {
override suspend fun getDataStore(
context: Context,
fileKey: String,
): DataStore<WidgetSymbolState> = context.widgetSymbolFile
override fun getLocation(context: Context, fileKey: String): File {
return context.dataStoreFile(widgetSymbolJson)
}
}
/*myObect2 - T is WidgetTableState*/
object StateDefinitionTable: GlanceStateDefinition<WidgetTableState> {
override suspend fun getDataStore(
context: Context,
fileKey: String,
): DataStore<WidgetTableState> = context.widgetTableFile
override fun getLocation(context: Context, fileKey: String): File {
return context.dataStoreFile(widgetTableJson)
}
}
@Serializable
data class WidgetSymbolState(
val index: Int = 0,
val portfolio: String = "Portfolio 1",
val portfolioSize: Int = 0,
val showPortfolioMenu: Boolean = false,
)
@Serializable
data class WidgetTableState(
val portfolioId: String = "",
val showPortfolioMenu: Boolean = false,
)
uj5u.com熱心網友回復:
對于編譯器錯誤,您需要向編譯器保證您可以呼叫copy. T但是,盡管兩者都有引數,但它們具有WidgetSymbolState.copy不同的簽名- 它們具有不同的引數,因為它們是從不同的資料類生成的。這意味著您不能在它們之間創建一個公共介面并將其放在那里。WidgetTableState.copyshowPortfolioMenucopy
我建議您updateShowPortfolioMenu在兩個類中添加一個方法,并將其用作公共介面。
interface ShowPortfolioMenuState<T: ShowPortfolioMenuState<T>> {
fun updateShowPortfolioMenu(newValue: Boolean): T
}
@Serializable
data class WidgetSymbolState(
val index: Int = 0,
val portfolio: String = "Portfolio 1",
val portfolioSize: Int = 0,
val showPortfolioMenu: Boolean = false,
): ShowPortfolioMenuState<WidgetSymbolState> {
override fun updateShowPortfolioMenu(newValue: Boolean) =
copy(showPortfolioMenu = newValue)
}
@Serializable
data class WidgetTableState(
val portfolioId: String = "",
val showPortfolioMenu: Boolean = false,
): ShowPortfolioMenuState<WidgetTableState> {
override fun updateShowPortfolioMenu(newValue: Boolean) =
copy(showPortfolioMenu = newValue)
}
然后你可以約束T到:GenericActionShowPortfolioMenuState
abstract class GenericAction<T: ShowPortfolioMenuState<T>>(...)
然后呼叫state.updateShowPortfolioMenu(showPortfolioMenu),而不是state.copy.
至于運行時錯誤,WidgetSymbolClass沒有采用Context. 我不確定你為什么要傳遞 acontext給它。要么不將背景關系傳遞給它:
myClass.getConstructor().newInstance()
或者添加一個Context引數,如果將傳遞給的其他類myClass 確實采用Context.
此外,您不需要@JvmOverloads. 任何地方都沒有可選引數。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/533010.html
