java - 如何在 Android 中执行 Java HTTP GET 调用并等待响应?

标签 java android http

我将尝试使其尽可能简单(这超出了我所见过的 Java HTTP 设置的范围)。

我的 Activity 中有一个决策树(伪):

private void okOnClick(View v){
   if(HttpService.isCredentialValid()){
     //wait to do something
   } else {
     //wait to do something else
   }
}

然后我有一个 HttpService:

public class HttpService {
   public static boolean isCredentialValid(){
     //GET `http://my_server:8080/is-valid?someParam=123`
     //the endpoint will return a 200 or 500
   }
}

我不希望 isCredentialValid 对 UI 执行任何操作,我只是希望它告诉我,是真是假。

我不想将其与 button.setText() 或任何其他内容紧密耦合,我只想要一个简单的合约 response.code == 200

在几乎所有语言中,这都不是那么困难。有人可以帮我纠正一下吗?

...对于任何敌意的声音感到抱歉。这是我使用过的几乎所有代码库中最基本的机制之一。我只发现异步模式无法向方法调用者返回实质性内容。或者我发现危及主线程的方法无法捕获错误(例如,当没有连接时)。

<小时/>

到目前为止,我已经尝试过类似下面的方法(调整代码以简化)。我允许它在主线程上操作,因为我确实希望它同步阻塞。然而,没有办法捕捉到互联网连接不良或远程服务器没有响应的情况:

 public static boolean isCredentialValid(){
    String url = "http://my_server:8080?param=123";
    StrictMode.ThreadPolicy policy = new 
    StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);

    try {
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(1, TimeUnit.SECONDS)
                .writeTimeout(1, TimeUnit.SECONDS)
                .readTimeout(1, TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder()
                .url(url)
                .build();


        Response response = client.newCall(request).execute();
        return response.code() == 200;
    } catch(Exception e){ 
        // 
        //THIS DOES NOT GET HIT WHEN THERE 
        //IS A BAD CONNECTION OR REMOTE SERVER FAILS TO RESPOND
        //the app just hangs then quits
        //
        Log.d("ERROR:", e.toString());
        return false;
    }
}

最佳答案

首先,您不应该在主线程上执行您的请求。此外,在 Android 上,HTTP 请求是异步执行的,如果您需要同步执行它们作为方法的返回,那么这是一种非常糟糕的做法,并且会产生代码味道。实现您想要实现的目标的正确方法是使用回调模式。您的方法不应返回任何内容,而应调用回调,该回调应作为其参数之一接收。如果您仍然非常需要同步执行操作,因为您不知道如何处理异步调用,或者您的架构不允许这样做,那么使用 CountDownLatch 怎么样?对不起,我的 Kotlin,但基本上它的工作原理是这样的:

val countDownLatch = CountDownLatch(1)

// Execute your request

countDownLatch.countDown()

try {
    countDownLatch.await(30, TimeUnit.SECONDS) // Give it a 30 seconds timeout
    // return the response code here.
} catch (ex: InterruptedException) {
    // Catch the timeout exception
}

无论如何,您可能应该重新考虑从该方法实际返回的必要性,而不是使用回调,我建议的并不完全是最佳实践。

PS:下面的代码确实是一个坏主意。基本上,您所做的就是强制 Android 在主线程上允许 HTTP 请求,这将完全阻止应用程序的 UI。

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

关于java - 如何在 Android 中执行 Java HTTP GET 调用并等待响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48939474/

相关文章:

http - 如何使用 cURL 执行 HTTP POST 值列表

java - 如何使用 FileReader 类打印我正在编写的程序

java - 为什么我只能在实体类上放置 NamedQuery 注释

android - 在应用程序中接受信用卡付款

java - 从多个路径从 Firebase 数据库获取数据

http - 元 http-equiv - 它是作为 HTTP header 的一部分发送的,还是客户端解析元标记的正文?

java - Spring 环境变量

java - 在客户端/服务器 Java 应用程序中保存用户名/密码的数据结构

Android JSONObject 在创建时跳过空值

http - tomcat/servlet 所需的多播(或类似)解决方案。