我正在尝试制作一个不断点击Google API来获取两点之间距离的应用程序,然后处理该距离并将其添加到循环内的db中。
我以前使用的是凌空抽射,但它不等待,我的函数继续执行其余的代码行。我需要帮助,以便代码行仅在我点击Google API后收到某种结果时才等待该方法返回,然后在下一行代码中使用该结果。
答案 0 :(得分:0)
您不能在主线程上进行同步调用。在网络调用上将UI线程阻塞超过指定的时间段将触发ANR。
有两个选择是使用AysncTask或AsyncTaskLoader。绝对不建议阻塞主线程。
AsyncTasks创建一个独立的执行线程,而UI线程可以继续其工作。
Android应用程序通常从单个执行线程开始,因此,如果您阻塞该线程,则将导致ANR。
看看here
如果您不介意用户无法接受的ANR,则可以使用简单的HttpURLConnection,但这是不推荐的。
如果您不喜欢AsyncTask方法,则可以创建一个Runnable进行后台处理,然后更新UI线程。
更多here
答案 1 :(得分:0)
我建议您调查协程。更具体地说,看一下async
启动器,它应该将值返回到等待变量。您的代码异步运行(启动一个新线程,这样您的主UI线程就不会阻塞,并且用户可以根据自己的意愿自由执行操作),并且当调用返回时,将在等待变量的位置再次调用您的代码。您可以在开始异步调用之前设置一个计时器,并在等待之后停止它。
您还可以使用withContext {}等待结果。当协程返回结果时,代码将在调用函数中继续。
startTimer()
val job = coroutineScope{
async{
networkCall()
}
}
job.await()
stopTimer()
或
startTimer()
coroutineScope{
launch{
withContext{
networkCall()
}
//code will continue when networkCall() has returned a result
stopTimer() //be careful, this may be called through a background thread.
}
}
协程是线程安全的和轻量级的,因此您可以启动任意数量的程序而不会出现任何问题。此外,通过使用coroutineScope
,您可以避免生命周期问题,例如ui旋转了,这通常会导致重新发送网络呼叫。使用coroutineScope
,您的呼叫将具有呼叫活动/片段的生命周期,因此,如果您的应用程序意外决定停止并且不再关心结果,它将被取消或终止。
希望这有帮助,Panos。
答案 2 :(得分:0)
如果您是初学者,请使用改造库进行API调用,其中选项enque
将为您调用API后台。
https://www.journaldev.com/13639/retrofit-android-example-tutorial
如果您是Pro,请使用Retrofit来使用Rxjava。 https://medium.com/3xplore/handling-api-calls-using-retrofit-2-and-rxjava-2-1871c891b6ae
答案 3 :(得分:0)
您可以实施jobservice以获取间隔内的距离。可以查看实施。here