如何解决Kotlin - Here Maps - 从回调函数中获取地址
我正在尝试从回调函数中获取地址。我一直在阅读 CallBacks 的文档和一些帖子,但仍然不明白为什么这不起作用,因为在返回“地址”变量时回调已经完成。
先谢谢你!
private fun getAddressForCoordinates(geoCoordinates: GeoCoordinates):String {
address = "unchanged"
val maxItems = 1
val reverseGeocodingOptions = SearchOptions(LanguageCode.EN_GB,maxItems)
searchEngine.search(geoCoordinates,reverseGeocodingOptions,addressSearchCallback)
return address
}
private val addressSearchCallback =
SearchCallback { searchError,list ->
if (searchError != null) {
//showDialog("Reverse geocoding","Error: $searchError")
Toast.makeText(context,"Error: $searchError",Toast.LENGTH_LONG).show()
return@SearchCallback
}
Toast.makeText(
context,"Reverse geocoded address:" + list!![0].address.addresstext,Toast.LENGTH_LONG
).show()
address = list[0].address.addresstext
}
解决方法
根据您的代码和评论,我假设您不熟悉异步执行的概念。这个概念很好地描述了here。我将引用主要观点:
当你同步执行某事时,你会等待它完成 在继续执行另一项任务之前。当你执行某事时 异步,您可以在完成之前继续执行另一个任务。
search()
需要提供回调并且它不只是返回搜索结果,这一事实很好地表明它很可能是异步的。调用它就像说:“在后台搜索数据,当你有数据时告诉我。这是我的电子邮件地址 - 请把我的结果发送给我”。其中电子邮件地址是您的回电。调用 search()
方法不会阻止代码的执行,也不会等待结果 - 它只会安排搜索并几乎立即返回。
异步处理通常比常规的同步代码更棘手,但在许多情况下它更有效。在您的情况下,您可以尝试“转换”库的原始异步 API 以同步您的代码期望的 API - 但这不是推荐的方法。或者,您可以重新设计代码,使其异步工作。例如,不要这样做:
fun yourMethodThatNeedsAddress() {
val address = getAddressForCoordinates()
doSomethingWithAddress(address)
}
你需要这样做:
fun yourMethodThatNeedsAddress() {
scheduleGetAddressForCoordinates() // renamed getAddressForCoordinates()
}
fun addressSearchCallback() {
...
doSomethingWithAddress(address)
}
因此,无论您计划对获取的地址做什么,您都不能在开始搜索后立即执行此操作。您需要等待回电,然后从那里继续处理您的地址。
,4.x HERE SDK 的 SearchEngine 需要在线连接,因为它从远程后端获取结果。这可能需要几毫秒,具体取决于您的网络连接。所以,无论何时执行搜索请求,都需要等到回调被调用:
searchEngine.search(geoCoordinates,reverseGeocodingOptions,addressSearchCallback)
当您调用它时,您将 addressSearchCallback
作为参数传递。 addressSearchCallback
的实现可能与您的示例类似。每当操作完成时都会调用它。如果设备离线,则会显示错误。
请注意,search()
方法不会立即返回任何结果。这些被传递给回调,它在后台线程上异步发生。因此,您的应用程序可以继续工作而不会阻塞任何 UI。
检索到结果后,HERE SDK 将在主线程上执行回调。
因此,如果您的代码需要对地址结果执行某些操作,则必须在 onSearchCompleted()
定义的 SearchCallback
方法中执行此操作。如果你用没有 lambda 符号的纯 Java 编写它,它会更明显:你创建一个新的 SearchCallback
对象并将它作为参数传递给搜索引擎。搜索引擎存储对象并在认为合适的时候执行对象的 onSearchCompleted()
:
private SearchCallback addressSearchCallback = new SearchCallback() {
@Override
public void onSearchCompleted(@Nullable SearchError searchError,@Nullable List<Place> list) {
if (searchError != null) {
showDialog("Reverse geocoding","Error: " + searchError.toString());
return;
}
// If error is null,list is guaranteed to be not empty.
showDialog("Reverse geocoded address:",list.get(0).getAddress().addressText);
// Here is the place to do something more useful with the Address object ...!
}
};
我取自 this GitHub 代码片段。请注意,还有一个 OfflineSearchEngine
,它可以在没有互联网连接的情况下工作,但出于某种原因,它遵循相同的模式并异步执行任务。
private void getAddressForCoordinates(GeoCoordinates geoCoordinates) {
int maxItems = 1;
SearchOptions reverseGeocodingOptions = new SearchOptions(LanguageCode.EN_GB,maxItems);
searchEngine.search(geoCoordinates,new SearchCallback() {
@Override
public void onSearchCompleted(@Nullable SearchError searchError,@Nullable List<Place> list) {
if (searchError != null) {
showDialog("Reverse geocoding","Error: " + searchError.toString());
return;
}
// If error is null,list is guaranteed to be not empty.
showDialog("Reverse geocoded address:",list.get(0).getAddress().addressText);
}
});
}
SearchEngine,需要提供一个 SearchOptions 实例来设置所需的 LanguageCode。它决定了结果地址的语言。然后我们可以调用引擎的search()方法在线搜索传递坐标的地址。如果出现错误,例如设备离线时,SearchError 会保存错误原因。
反向地理编码响应包含错误或结果:SearchError 和结果列表不能同时为空 - 或同时为非空。
包含在每个 Place 实例中的 Address 对象是一个数据类,其中包含多个描述原始位置地址的 String 字段,例如国家、城市、街道名称等等。有关更多详细信息,请参阅 API 参考。如果您只对接收可读的地址表示感兴趣,则可以访问 addressText,如上例所示。这是一个字符串,其中包含最相关的地址详细信息,包括地点的标题。
有关 search() 函数及其相关参数的详细文档,请参阅以下链接。
https://developer.here.com/documentation/android-sdk-explore/4.4.0.2/dev_guide/topics/search.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。