如何在Android中进行同步网络通话?

时间:2019-11-28 07:19:09

标签: android

我正在尝试制作一个不断点击Google API来获取两点之间距离的应用程序,然后处理该距离并将其添加到循环内的db中。

我以前使用的是凌空抽射,但它不等待,我的函数继续执行其余的代码行。我需要帮助,以便代码行仅在我点击Google API后收到某种结果时才等待该方法返回,然后在下一行代码中使用该结果。

4 个答案:

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