【问题标题】:How to make a synchronous call using Retrofit on Android如何在 Android 上使用 Retrofit 进行同步调用
【发布时间】:2017-11-23 17:40:20
【问题描述】:

我在一个想要同步运行的 android 应用中有一个登录视图。也就是说,我希望用户留在页面上,直到登录休息调用完成。如果失败,用户可以重新输入他们的 ID 和密码。如果成功,他们将被路由到欢迎页面。

Retrofit 提供了如何进行同步调用的示例。但它带有一个警告,“同步请求会在 Android 4.0 或更高版本上触发应用程序崩溃。您将遇到NetworkOnMainThreadException 错误。”我在 stackoverflow 上看到了各种响应,包括使用 Otto 和 Robospice。其他人使用本地侦听器,其他人使用同步请求。

实现此功能的最简单、最安全的方法是什么。

【问题讨论】:

    标签: android rest retrofit robospice otto


    【解决方案1】:

    如果您在改造中运行同步调用,应用将在 Android 4.0 或更高版本上崩溃。你会遇到NetworkOnMainThreadException 错误。同步方法提供了直接使用返回值的能力,因为该操作会在您的网络请求期间阻塞其他所有内容。

    对于非阻塞 UI,您必须自己在单独的线程中处理请求执行。这意味着,您仍然可以在等待响应时与应用程序本身进行交互。参考:enter link description here

    【讨论】:

      【解决方案2】:

      你不需要同步请求来实现这个..

      同步请求在主线程上执行。在 android 中,主线程用于绘制您的 UI,因此在该线程上执行网络请求会阻塞您的 UI,因此 Android 会引发异常。

      异步请求在单独的线程中执行网络连接,并通过回调将信息传递回主线程。这就是你需要的。

      这是使用 Retrofit 的示例代码在您的情况下的样子

      call.enqueue(new Callback<LoginResponse>() {  
          @Override
          public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
              if (response.isSuccessful()) {
                  // status code 2xx. start welcome activity
              } else {
                  // Recieved a response but not 2xx. 
                  // Possibly authentication error. Show error message
      
              }
          }
      
          @Override
          public void onFailure(Call<LoginResponse> call, Throwable t) {
              // request could not be executed ( possibly no internet connection)
      
          }
      }
      

      【讨论】:

      • 这就是我目前正在做的事情。问题是如何将结果返回给我的调用片段。我可以传递片段的一个实例,但这似乎不是最好的事情,因为片段可能会消失。或者我可以使用 Otto 或 Robospice 之类的东西,但这似乎有点矫枉过正。另外,我想在登录屏幕上显示正在进行身份验证的一些表示,这样他们就不会离开。
      • 这就是onResponse 的用途。它将响应传递给您的呼叫活动/片段。您可以在 enqueue 调用之前显示一个不确定的 ProgressBar 并将其隐藏在 onResponse 块中
      • 是的,我明白了。正如我所说,这就是我目前正在做的事情。我想将我的登录休息请求放在一个单独的类中(用于测试、重用等),所有逻辑都与发送和获取我的响应相关联,而不是在片段或活动中。然后让片段在我的休息服务类上调用一个方法并在完成时收到通知。
      • 您应该考虑所有要求并在提出问题时清楚地说明它们。根据您的 cmets,您提出的问题与您作为 cmets 发布的内容几乎无关。话虽如此,Retrofit 的Callback 是一个接口,您的片段可以implement 并处理响应。
      • 问题是关于同步调用请求而不是异步调用。例如:在服务中进行 n/w 调用,然后在 onResponse() 中更新 SQLite 数据库。这种情况需要 Sync 调用,而 Async 将不起作用。
      猜你喜欢
      • 1970-01-01
      • 2015-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-28
      • 2017-09-09
      • 2018-02-01
      • 2014-08-23
      相关资源
      最近更新 更多