解释基本的Kotlin功能

时间:2018-12-06 20:05:05

标签: android kotlin

我是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()之类的东西,但我又回到了最初的问题:如何使updateAppWidgetwidgetText之外可用并退货。

2 个答案:

答案 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) }