我是Java / Kotlin的新手,正在研究此tutorial,以使用可从URL查询某些JSON并呈现所述结果的小部件构建Android应用。
我对最后的代码示例感到困惑:
val service = ServiceVolley()
val apiController = APIController(service)
val path = "example_endpoint"
val params = JSONObject()
params.put("email", "foo@email.com")
params.put("password", "barpass")
apiController.post(path, params) { response ->
// Parse the result
}
通常在Kotlin中,如果函数的最后一个参数是一个函数(并且您将lambda表达式作为相应的参数传递),则可以在括号外指定它,就像上面所做的那样-我对Kotlin的一些小怪癖。
在我的窗口小部件代码中,我有一个辅助函数updateAppWidget
,在其中我可以使用上面的代码,并且可以成功查询API,但是我最终得到了{{1 }}函数内部 updateAppWidget
块:
{ response -> // Parse the result }
有人可以解释 first 代码块的后三行的含义,并告诉我如何编写此代码以将逻辑提升到一个水平,这是否值得一遍? / p>
我注意到的直接问题是我无法在此块之外引用widgetText。
为清楚起见进行编辑
我觉得我很烦。进一步的阅读表明我正在通过使用apiController.post(path,params) { response ->
// Get 'bar' from the response which is {'foo':'bar'}
val widgetText = response?.get(response.names().getString(0)).toString()
// Construct the RemoteViews object
val views = RemoteViews(context.packageName, R.layout.statusr)
views.setTextViewText(R.id.appwidget_text, widgetText)
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views)
}
传递lambda?我想我真正想做的是:
完全从小部件代码中获取对->
的调用,因此现在在单独的类中进行调用:
apiController.post
我希望能够在class GetData {
fun widget_text(){
val service = ServiceVolley()
val apiController = APIController(service)
val path = "endpoint"
val params = JSONObject()
params.put("some", "data")
apiController.post(path, params) { response ->
val widgetText = response?.get(response.names().getString(0)).toString()
}
}
}
内调用类似GetData.widget_text()
之类的东西,但我又回到了最初的问题:如何使updateAppWidget
在widgetText
之外可用并退货。
答案 0 :(得分:1)
最后三行的含义: params 中的数据被传递到某种类型的后端(服务器)。
apiController.post(path, params) { response ->
val widgetText = response?.get(response.names().getString(0)).toString()
// Display the result in the App Widget
}
该请求是异步执行的。这意味着,lambda表达式中的代码将在服务器响应进入后运行,而应用程序的UI将保持可单击状态。启动后端调用的方法将已经完成(如果必须等待直到响应出现在UI中,则该方法可能会冻结)。
使用GetData
作为管理后端调用的类的可能应用结构:
class GetData {
interface WidgetTextCallback {
fun onTextLoaded(text: String)
}
companion object {
fun widget_text(callback: WidgetTextCallback) {
val service = ServiceVolley()
val apiController = APIController(service)
val path = "endpoint"
val params = JSONObject()
params.put("some", "data")
apiController.post(path, params) { response ->
val widgetText = response?.get(response.names().getString(0)).toString()
callback.onTextLoaded(widgetText)
}
}
}
}
并使用该界面来检索小部件文本:
class NewAppWidget : AppWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
GetData.widget_text(object: GetData.WidgetTextCallback{
override fun onTextLoaded(widgetText: String) {
// There may be multiple widgets active, so update all of them
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, widgetText, appWidgetManager, appWidgetId)
}
}
})
}
companion object {
internal fun updateAppWidget(context: Context, widgetText: String, appWidgetManager: AppWidgetManager,
appWidgetId: Int) {
// Construct the RemoteViews object
val views = RemoteViews(context.packageName, R.layout.new_app_widget)
views.setTextViewText(R.id.appwidget_text, widgetText)
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
}
答案 1 :(得分:0)
“将此逻辑提升到一个新的水平”听起来就像您想在代码的其他地方处理响应。为什么不将其传递给处理函数呢?
fun handleResponse(response: Type?) {
// Parse the result
}
apiController.post(path, params) { response ->
handleResponse(response)
}
或更短:
apiController.post(path, params) { handleResponse(it) }