8

I'm using Android Studio, and I've spent a few hours trying to do a simple HTTP request in my MainActivity.java file, and tried multiple ways, and seen many web pages on the subject, yet cannot figure it out.

When I try OkHttp, I get a error about not being able to do it on the main thread. Now I'm trying to do it this way:

public static String getUrlContent(String sUrl) throws Exception {
    URL url = new URL(sUrl);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("GET");
    connection.setDoOutput(true);
    connection.setConnectTimeout(5000);
    connection.setReadTimeout(5000);
    connection.connect();
    BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    String content = "", line;
    while ((line = rd.readLine()) != null) {
        content += line + "\n";
    }
    return content;
}

I put that method directly in MainActivity.java, and my click event executes it from another method that is also in MainActivity.java:

try {
    String str = getUrlContent("https://example.com/WAN_IP.php");
    displayMessage(str);
}
catch(Exception e){
    displayMessage(e.getMessage());
}

But right now there is no crash, and I can tell there is an exception thrown on the line that starts "BufferedReader", but e.getMessage() is blank.

I'm brand new to Android Studio and java, so please be kind and help me with this very basic problem. Eventually I will need to do post requests to the server, and it seems that OkHttp is the best way to go, but I'm not finding the "Hello World" of OkHttp in Android Studio documented anywhere online.

Brian Gottier
  • 4,522
  • 3
  • 21
  • 37
  • Take a look at [this](https://stackoverflow.com/a/38313386/6535244) answer. It is not possible to open HTTP connection in the main thread (and this is why you got this first error) and using `AsyncTask` is a good way of dealing with this – cieplik Jul 26 '16 at 15:05
  • I think you overestimate my knowledge of Android Studio and java. The link I'm sure shows a good answer, but I don't know what to do with the code. I don't know where to put it. I see in the docs for AsyncTask that it should be added to the main thread, but I don't know how to do that, or what that means. – Brian Gottier Jul 26 '16 at 15:40
  • Related: https://stackoverflow.com/q/46177133/8583692 – Mahozad Dec 31 '21 at 19:13

3 Answers3

21

You should not make network requests on the main thread. The delay is unpredictable and it could freeze the UI.

Android force this behaviour by throwing an exception if you use the HttpUrlConnection object from the main thread.

You should then make your network request in the background, and then update the UI on the main thread. The AsyncTask class can be very handy for this use case !

private class GetUrlContentTask extends AsyncTask<String, Integer, String> {
     protected String doInBackground(String... urls) {
        URL url = new URL(urls[0]);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setDoOutput(true);
        connection.setConnectTimeout(5000);
        connection.setReadTimeout(5000);
        connection.connect();
        BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String content = "", line;
        while ((line = rd.readLine()) != null) {
            content += line + "\n";
        }
        return content;
     }

     protected void onProgressUpdate(Integer... progress) {
     }

     protected void onPostExecute(String result) {
         // this is executed on the main thread after the process is over
         // update your UI here
         displayMessage(result);
     }
 }

And you start this process this way:

new GetUrlContentTask().execute(sUrl)
Nicolas Dusart
  • 1,867
  • 18
  • 26
  • OK, your code was most helpful, but it did require some tweaking. Android Studio helped debug, and it works! – Brian Gottier Jul 26 '16 at 16:43
  • Is "connection.connect()" necessary? Doesn't "url.openConnection()" already accomplish this? – Abdel Aleem Apr 17 '22 at 09:26
  • `openConnection` does not automatically connect the connection as some methods can only be called on connection that is not connected yet. But the `connect` may not be mandatory as some functions requiring a connected connection will implicitly call it but as the list is not exhaustively documented, I think it is preferrable to call it anyway. – Nicolas Dusart Apr 17 '22 at 11:16
0

if your using okhttp then call aysnc try bellow code

 private final OkHttpClient client = new OkHttpClient();

  public void run() throws Exception {
    Request request = new Request.Builder()
        .url("http://publicobject.com/helloworld.txt")
        .build();
     client.setConnectTimeout(15, TimeUnit.SECONDS);
    client.newCall(request).enqueue(new Callback() {
      @Override public void onFailure(Call call, IOException e) {
        e.printStackTrace();
      }

      @Override public void onResponse(Call call, Response response) throws IOException {
        if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

        Headers responseHeaders = response.headers();
        for (int i = 0, size = responseHeaders.size(); i < size; i++) {
          Log.e(responseHeaders.name(i) , responseHeaders.value(i));
        }

       Log.e("response",response.body().string());
      }
    });
  }
0

You can use dependency for making HTTP requests or HTTPS request,Use OkHttp

Visit :https://square.github.io/okhttp

 OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
  Request request = new Request.Builder()
      .url(url)
      .build();

  try (Response response = client.newCall(request).execute()) {
    return response.body().string();
  }
}
Predator_Shek
  • 71
  • 1
  • 2