android - 解释这个基本的 Kotlin 函数
问题描述
我是 Java/Kotlin 的新手,正在通过本教程构建一个带有小部件的 Android 应用程序,该小部件可以从 URL 查询一些 JSON 并呈现所述结果。
我对最后一个代码示例感到困惑:
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,但是我最终得到了块内updateAppWidget
函数中的大部分代码:{ response -> // Parse the result }
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)
}
有人可以解释第一个代码块的最后 3 行的重要性,并告诉我如何编写它以将逻辑提升一个级别,这是否值得?
我注意到的直接问题是我不能在这个块之外引用 widgetText。
为清楚起见进行编辑
我想我在我的头上。进一步阅读表明我正在通过使用->
? 我想我真正想做的是:
完全摆脱小部件代码的调用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
外部提供apiController.post(path,params) { response -> // Logic }}
并返回它。
解决方案
前三行的含义: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)
}
}
}
推荐阅读
- android - 如果我们的 .png 可绘制图像使用恒定的 DP 尺寸,那么我们是否为每个屏幕尺寸提供不同的 .png 是否重要?
- html - HTML 表单是在不使用 JS 的情况下发出 POST 请求的唯一方法吗?
- sql - 在大查询中对列进行选择时,有没有办法解析 url 字符串?
- c# - 将 HttpWebRequest 转换为 UnityWebRequest
- c# - 为什么运算符方法在 C# 中应该是静态的?
- c# - 使用 if 语句显示到文本框中
- python - 如何解决 Django 中显示“无法解析剩余部分”的 TemplateSyntaxError
- r - 安装字体以便 R postscript() 设备可以识别它们
- asp.net-mvc - 如果不需要,如何创建不更改 HttpContext 的处理程序?(Asp.Net MVC)
- python - 索引超出范围(python if 循环)