안드로이드로 HTTP 요청하기


352

어디에서나 검색했지만 답변을 찾을 수 없습니다. 간단한 HTTP 요청을 할 수있는 방법이 있습니까? 내 웹 사이트 중 하나에서 PHP 페이지 / 스크립트를 요청하고 싶지만 웹 페이지를 표시하고 싶지 않습니다.

가능하면 백그라운드에서 (BroadcastReceiver에서)하고 싶습니다.


답변:


477

최신 정보

이것은 매우 오래된 답변입니다. 나는 더 이상 아파치의 클라이언트를 추천하지 않을 것이다. 대신 다음 중 하나를 사용하십시오.

원래 답변

우선 네트워크 액세스 권한을 요청하고 매니페스트에 다음을 추가하십시오.

<uses-permission android:name="android.permission.INTERNET" />

그런 다음 가장 쉬운 방법은 Android와 함께 번들로 제공된 Apache http 클라이언트를 사용하는 것입니다.

    HttpClient httpclient = new DefaultHttpClient();
    HttpResponse response = httpclient.execute(new HttpGet(URL));
    StatusLine statusLine = response.getStatusLine();
    if(statusLine.getStatusCode() == HttpStatus.SC_OK){
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        response.getEntity().writeTo(out);
        String responseString = out.toString();
        out.close();
        //..more logic
    } else{
        //Closes the connection.
        response.getEntity().getContent().close();
        throw new IOException(statusLine.getReasonPhrase());
    }

별도의 스레드에서 실행하려면 AsyncTask를 확장하는 것이 좋습니다.

class RequestTask extends AsyncTask<String, String, String>{

    @Override
    protected String doInBackground(String... uri) {
        HttpClient httpclient = new DefaultHttpClient();
        HttpResponse response;
        String responseString = null;
        try {
            response = httpclient.execute(new HttpGet(uri[0]));
            StatusLine statusLine = response.getStatusLine();
            if(statusLine.getStatusCode() == HttpStatus.SC_OK){
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                response.getEntity().writeTo(out);
                responseString = out.toString();
                out.close();
            } else{
                //Closes the connection.
                response.getEntity().getContent().close();
                throw new IOException(statusLine.getReasonPhrase());
            }
        } catch (ClientProtocolException e) {
            //TODO Handle problems..
        } catch (IOException e) {
            //TODO Handle problems..
        }
        return responseString;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        //Do anything with response..
    }
}

그런 다음 다음을 통해 요청할 수 있습니다.

   new RequestTask().execute("http://stackoverflow.com");

11
다음은 AsyncTask의 공식 안드로이드 개발자 블로그 기사입니다 : android-developers.blogspot.com/2010/07/…
Austyn Mahoney

77
진저 브레드 이상의 경우 아파치 라이브러리를 통해 HttpURLConnection을 사용하는 것이 좋습니다 . android-developers.blogspot.com/2011/09/… 배터리에 대한 세금이 적고 성능이 더 좋습니다
Marty

8
responseString = out.toString ()은 out.close () 호출 이전에 있어야합니다. 실제로 finally 블록에 out.close ()가 있어야합니다. 그러나 전반적으로 매우 유용한 답변 (+1), 감사합니다!
dcp

9
Honeycomb (SDK 11)부터는 비동기식 접근 방식이 필요합니다. NetworkOnMainThreadException는 메인 스레드에서 HTTP 요청을 실행하려고했을 경우에 슬로우됩니다.
msrxthr

2
이 답변은 매우 우수합니다. 그러나 네트워킹에는 AsyncTasks를 사용하지 않는 것이 좋습니다. 메모리 누수를 매우 쉽게 생성 할 수 있으며 실제로 제공된 예제는 누수를 발생시킬 수 있으며 네트워크 요청에 필요한 모든 기능을 제공하지는 않습니다. 이런 종류의 백그라운드 작업에 RoboSpice를 사용해보십시오. github.com/octo-online/robospice
Snicolas

67

Apache HttpClient를 선택해야하는 명백한 이유가 없으면 java.net.URLConnection을 선호해야합니다. 웹에서 사용하는 방법에 대한 많은 예를 찾을 수 있습니다.

원래 게시물 이후로 Android 설명서도 개선되었습니다. http://developer.android.com/reference/java/net/HttpURLConnection.html

우리는 공식 블로그 ( http://android-developers.blogspot.com/2011/09/androids-http-clients.html) 에서 장단점에 대해 이야기했습니다.


13
Apache HttpClient를 사용하지 않는 이유는 무엇입니까?
Ted

4
내 공동 음모는 공식 블로그 ( android-developers.blogspot.com/2011/09/)
Elliott Hughes

@ElliottHughes : 100 % 동의합니다. Apache httpclient가 쉬운 메소드와보다 추상적 인 프로토콜보기를 제공한다는 것을 부인할 수는 없지만, Java의 기본 URL 연결은 그다지 유용하지 않습니다. 손 -에, 그와 같은 사용하기 쉬운 HttpClient를 등의 비트와 함께 방법이 더 휴대용
니틴 반살

1
실제로 비디오 Google I / O 2010-Android REST 클라이언트 애플리케이션 ( youtube.com/watch?v=xHXn3Kg2IQE 57min21sec)을 살펴보면 Apache HttpClient가 가장 권장되는 것을 볼 수 있습니다. Virgil Dobjanschi (Android 응용 프로그램 그룹에서 작동하는 Google의 소프트웨어 엔지니어)는 "저는 더 강력한 구현이 있기 때문에 HTTP Apache 클라이언트를 사용하는 것이 좋습니다. HTTP 트랜잭션의 URL 연결 유형이 가장 효율적이지 않습니다. 연결을 종료하는 방식이 네트워크에 악영향을 미칠 수 있습니다. "
Alan

46

참고 : Android와 번들로 제공되는 Apache HTTP 클라이언트는 이제 HttpURLConnection 을 위해 더 이상 사용되지 않습니다 . 자세한 내용은 Android 개발자 블로그 를 참조하십시오.

<uses-permission android:name="android.permission.INTERNET" />매니페스트에 추가 하십시오.

그런 다음 다음과 같이 웹 페이지를 검색하십시오.

URL url = new URL("http://www.android.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
     readStream(in);
}
finally {
     urlConnection.disconnect();
}

또한 별도의 스레드에서 실행하는 것이 좋습니다.

class RequestTask extends AsyncTask<String, String, String>{

@Override
protected String doInBackground(String... uri) {
    String responseString = null;
    try {
        URL url = new URL(myurl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        if(conn.getResponseCode() == HttpsURLConnection.HTTP_OK){
            // Do normal input or output stream reading
        }
        else {
            response = "FAILED"; // See documentation for more info on response handling
        }
    } catch (ClientProtocolException e) {
        //TODO Handle problems..
    } catch (IOException e) {
        //TODO Handle problems..
    }
    return responseString;
}

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
    //Do anything with response..
}
}

응답 처리 및 POST 요청에 대한 자세한 내용은 설명서 를 참조하십시오 .


1
@Semmix 어떻게 그렇게? 질문은 "간단한 HTTP"요청을 요청했으며 내 코드는 정확하게 수행합니다.
kevinc

1
첫 번째 코드 블록은 Android 문서에서 복사하여 붙여 넣지 만 사람은 샘플 / 문서 쓰레기입니다. readStream심지어 정의되지 않았습니다.
Eugene K

@EugeneK이 질문에 대답 할 수있는 가장 간단한 방법 일 것입니다. Android에서 HTTP 요청을 올바르게 수행하려면 Retrofit 및 OkHttp에 대해 설명해야합니다. 나는 초보자가 잘못 구성되어 있어도 기술적으로 간단한 HTTP 요청을하는 스 니펫을 나눠주는 것 이상을 혼란스럽게 생각합니다.
kevinc

12

가장 간단한 방법은 Volley 라는 Android 라이브러리를 사용하는 것입니다.

발리는 다음과 같은 이점을 제공합니다.

네트워크 요청의 자동 예약. 여러 개의 동시 네트워크 연결 . 표준 HTTP 캐시 일관성을 갖춘 투명한 디스크 및 메모리 응답 캐싱. 요청 우선 순위 지원. 취소 요청 API. 단일 요청을 취소하거나 취소 할 요청 블록 또는 범위를 설정할 수 있습니다. 재시도 및 백 오프와 같은 사용자 정의가 용이합니다. 네트워크에서 비동기식으로 가져온 데이터로 UI를 올바르게 채울 수있는 강력한 순서입니다. 디버깅 및 추적 도구.

다음과 같이 간단하게 http / https 요청을 보낼 수 있습니다.

        // Instantiate the RequestQueue.
        RequestQueue queue = Volley.newRequestQueue(this);
        String url ="http://www.yourapi.com";
        JsonObjectRequest request = new JsonObjectRequest(url, null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    if (null != response) {
                         try {
                             //handle your response
                         } catch (JSONException e) {
                             e.printStackTrace();
                         }
                    }
                }
            }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });
        queue.add(request);

이 경우, 모두 이미 발리에서 수행 했으므로 "백그라운드에서 실행"또는 "캐시 사용"을 고려할 필요가 없습니다.


6
private String getToServer(String service) throws IOException {
    HttpGet httpget = new HttpGet(service);
    ResponseHandler<String> responseHandler = new BasicResponseHandler();
    return new DefaultHttpClient().execute(httpget, responseHandler);

}

문안 인사


4

실로 :

private class LoadingThread extends Thread {
    Handler handler;

    LoadingThread(Handler h) {
        handler = h;
    }
    @Override
    public void run() {
        Message m = handler.obtainMessage();
        try {
            BufferedReader in = 
                new BufferedReader(new InputStreamReader(url.openStream()));
            String page = "";
            String inLine;

            while ((inLine = in.readLine()) != null) {
                page += inLine;
            }

            in.close();
            Bundle b = new Bundle();
            b.putString("result", page);
            m.setData(b);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        handler.sendMessage(m);
    }
}

4

웹 서비스가 Gson lib를 사용하여 URL을 다시 요청하기 위해 이것을 만들었습니다.

고객:

public EstabelecimentoList getListaEstabelecimentoPorPromocao(){

        EstabelecimentoList estabelecimentoList  = new EstabelecimentoList();
        try{
            URL url = new URL("http://" +  Conexao.getSERVIDOR()+ "/cardapio.online/rest/recursos/busca_estabelecimento_promocao_android");
            HttpURLConnection con = (HttpURLConnection) url.openConnection();

            if (con.getResponseCode() != 200) {
                    throw new RuntimeException("HTTP error code : "+ con.getResponseCode());
            }

            BufferedReader br = new BufferedReader(new InputStreamReader((con.getInputStream())));
            estabelecimentoList = new Gson().fromJson(br, EstabelecimentoList.class);
            con.disconnect();

        } catch (IOException e) {
            e.printStackTrace();
        }
        return estabelecimentoList;
}

4

gradle을 통해 사용할 수있는이 멋진 새 라이브러리를보십시오 :)

build.gradle : compile 'com.apptakk.http_request:http-request:0.1.2'

용법:

new HttpRequestTask(
    new HttpRequest("http://httpbin.org/post", HttpRequest.POST, "{ \"some\": \"data\" }"),
    new HttpRequest.Handler() {
      @Override
      public void response(HttpResponse response) {
        if (response.code == 200) {
          Log.d(this.getClass().toString(), "Request successful!");
        } else {
          Log.e(this.getClass().toString(), "Request unsuccessful: " + response);
        }
      }
    }).execute();

https://github.com/erf/http-request


1
다른 모든 도서관처럼 보인다 ...
Nick Gallimore

3

위에서 제안한대로 발리를 사용하십시오. build.gradle에 다음을 추가하십시오 (모듈 : app).

implementation 'com.android.volley:volley:1.1.1'

AndroidManifest.xml에 다음을 추가하십시오.

<uses-permission android:name="android.permission.INTERNET" />

그리고 당신에게 활동 코드를 추가하십시오 :

public void httpCall(String url) {

    RequestQueue queue = Volley.newRequestQueue(this);

    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    // enjoy your response
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    // enjoy your error status
                }
    });

    queue.add(stringRequest);
}

http 클라이언트를 대체하며 매우 간단합니다.


2

이것은 안드로이드의 HTTP Get / POST 요청을위한 새로운 코드입니다. HTTPClient사용되지 않으며 제 경우와 같이 사용하지 못할 수 있습니다.

먼저 build.gradle에 두 가지 종속성을 추가하십시오.

compile 'org.apache.httpcomponents:httpcore:4.4.1'
compile 'org.apache.httpcomponents:httpclient:4.5'

그런 다음이 코드 ASyncTaskdoBackground메소드 에 작성하십시오 .

 URL url = new URL("http://localhost:8080/web/get?key=value");
 HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
 urlConnection.setRequestMethod("GET");
 int statusCode = urlConnection.getResponseCode();
 if (statusCode ==  200) {
      InputStream it = new BufferedInputStream(urlConnection.getInputStream());
      InputStreamReader read = new InputStreamReader(it);
      BufferedReader buff = new BufferedReader(read);
      StringBuilder dta = new StringBuilder();
      String chunks ;
      while((chunks = buff.readLine()) != null)
      {
         dta.append(chunks);
      }
 }
 else
 {
     //Handle else
 }

이 코드는 더 이상 사용되지 않을 수 있으며 Apache는 더 이상 Android Platform API 28에서 지원되지 않습니다.이 경우 Manifest 또는 모듈 레벨 Gradle 파일에서 Apache 레거시 속성을 활성화 할 수 있습니다. 그러나 OKHttp, Volley 또는 Retrofit 네트워킹 라이브러리를 사용하는 것이 좋습니다.
Rahul Raina 2016 년

1

나에게 가장 쉬운 방법은 Retrofit2 라는 라이브러리를 사용하는 것입니다.

요청 메소드, 매개 변수를 포함하는 인터페이스를 작성해야하며 각 요청에 대해 사용자 정의 헤더를 작성할 수도 있습니다.

    public interface MyService {

      @GET("users/{user}/repos")
      Call<List<Repo>> listRepos(@Path("user") String user);

      @GET("user")
      Call<UserDetails> getUserDetails(@Header("Authorization") String   credentials);

      @POST("users/new")
      Call<User> createUser(@Body User user);

      @FormUrlEncoded
      @POST("user/edit")
      Call<User> updateUser(@Field("first_name") String first, 
                            @Field("last_name") String last);

      @Multipart
      @PUT("user/photo")
      Call<User> updateUser(@Part("photo") RequestBody photo, 
                            @Part("description") RequestBody description);

      @Headers({
        "Accept: application/vnd.github.v3.full+json",
        "User-Agent: Retrofit-Sample-App"
      })
      @GET("users/{username}")
      Call<User> getUser(@Path("username") String username);    

    }

가장 좋은 방법은 enqueue 메서드를 사용하여 비동기 적으로 쉽게 할 수 있다는 것입니다.


1

답변 중 어느 것도 OkHttp로 요청을 수행하는 방법을 설명하지 않았 으므로 요즘에는 Android 및 Java에서 일반적으로 널리 사용되는 http 클라이언트입니다. 간단한 예제를 제공하려고합니다.

//get an instance of the client
OkHttpClient client = new OkHttpClient();

//add parameters
HttpUrl.Builder urlBuilder = HttpUrl.parse("https://www.example.com").newBuilder();
urlBuilder.addQueryParameter("query", "stack-overflow");


String url = urlBuilder.build().toString();

//build the request
Request request = new Request.Builder().url(url).build();

//execute
Response response = client.newCall(request).execute();

이 라이브러리의 분명한 장점은 하위 수준의 세부 정보에서 우리를 추상화하여보다 친절하고 안전한 상호 작용 방법을 제공한다는 것입니다. 구문도 단순화되어 멋진 코드를 작성할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.