如何在Android中执行JavaHTTPGET调用并等待响应?

如何在Android中执行JavaHTTPGET调用并等待响应?,java,android,http,Java,Android,Http,我将尽可能地简化这个过程(对于我所看到的JavaHTTP设置,这比我所能说的要多) 我的活动中有一个决策树(伪): private void okOnClick(View v){ if(HttpService.isCredentialValid()){ //wait to do something } else { //wait to do something else } } 然后我有一个HttpService: public class HttpSer

我将尽可能地简化这个过程(对于我所看到的JavaHTTP设置,这比我所能说的要多)

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

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执行任何操作,我只希望它告诉我,是真是假

我不想把它与
按钮.setText()
或其他任何东西紧密结合,我只想要一个简单的契约
response.code==200

在几乎所有的语言中,这并不是那么难。有人能在这儿帮我直说一下吗

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


到目前为止,我已经尝试了下面的方法(调整代码以简化)。我允许它在主线程上运行,因为我确实希望它同步阻塞。但是,无法了解internet连接不良或远程服务器没有响应的情况:

 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请求是异步执行的,如果您需要将它们作为方法的返回同步执行,那么这是一种非常糟糕的做法和代码味道。正确的实现方法是使用回调模式。您的方法不应该返回任何内容,而是调用一个回调,该回调应作为其参数之一接收。如果由于您不知道如何处理异步调用或者您的体系结构不允许异步调用,您仍然有同步处理的极端必要性,那么使用
倒计时闩锁
怎么样?请原谅我的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);

你有没有试着根据它的值设置一个布尔变量,你可以执行你想要的操作?只是好奇,你用了什么?现在更新原始问题…当然,这是可以理解的,发现代码附带了大量警告。然而,我希望有一种安全的方法来线性执行纯事务(阻塞主线程)。如果存在一个适当的超时和try-catch(意味着所有的场景都被覆盖了,这似乎不是),那么在某些情况下阻塞主线程是一件合理的事情。我感谢您的响应。我认为你的想法完全正确,涵盖了应用程序开发人员更常见的场景。我会接受答案,因为在99.9%的情况下,它是正确的。阻止主线程通常不是一个好主意。还有其他方法可以避免阻塞主线程,但仍然能够完全控制整个情况。如果需要同步性,回调模式会提供同步性,而不会阻塞应用程序的UI或导致ANR风险。我知道您可能需要重构应用程序的某些部分,但试一试,也许您会发现它正是您所寻求的解决方案:)