Android ile HTTP isteği yapma


Yanıtlar:


477

GÜNCELLEME

Bu çok eski bir cevap. Kesinlikle artık Apache'nin müşterisini tavsiye etmeyeceğim. Bunun yerine aşağıdakilerden birini kullanın:

Orijinal Yanıt

Her şeyden önce, ağa erişim izni isteyin, manifestinize aşağıdakileri ekleyin:

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

O zaman en kolay yol Android ile birlikte gelen Apache http istemcisini kullanmaktır:

    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());
    }

Ayrı bir iş parçacığında çalışmasını istiyorsanız AsyncTask'ın genişletilmesini öneririm:

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..
    }
}

Daha sonra şu şekilde bir istekte bulunabilirsiniz:

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

11
İşte AsyncTask resmi android geliştirici blogundan bir makale: android-developers.blogspot.com/2010/07/…
Austyn Mahoney

77
zencefilli kurabiye veya daha fazlası için apache kütüphanesi üzerinde aslında HttpURLConnection kullanılması tavsiye edilir, bkz. android-developers.blogspot.com/2011/09/… . Pilden daha az vergi alıyor ve daha iyi performansa sahip
Marty

8
responseString = out.toString (), out.close () çağrısından önce olmalıdır. Aslında, sonunda bir blokta out.close () yöntemine sahip olmalısınız. Ama genel olarak, çok yararlı cevap (+1), teşekkürler!
dcp

9
Honeycomb'dan (SDK 11) itibaren asenkron yaklaşım yoludur. Ana iş parçacığından bir HTTP isteği çalıştırmayı denediğinizde bir NetworkOnMainThreadException atılır.
msrxthr

2
Bu cevap oldukça mükemmel. Ama AsyncTasks'ı Ağ için kullanmamanızı tavsiye ederim. Bellek sızıntılarını çok kolay bir şekilde oluşturabilirler (ve aslında sağlanan örnek sızıntı yapar) ve ağ istekleri için bekleyebileceği tüm özellikleri sağlamazlar. Bu tür arka plan görevleri için RoboSpice kullanmayı düşünün: github.com/octo-online/robospice
Snicolas

67

Apache HttpClient'i seçmek için açık bir nedeniniz yoksa java.net.URLConnection'ı tercih etmelisiniz. web'de nasıl kullanılacağına dair birçok örnek bulabilirsiniz.

orijinal yayınınızdan bu yana Android dokümanlarını da geliştirdik: http://developer.android.com/reference/java/net/HttpURLConnection.html

ve resmi blogda ödünleşmelerden bahsettik: http://android-developers.blogspot.com/2011/09/androids-http-clients.html


13
Apache HttpClient kullanımı neden önerilmez?
Ted

4
Bir yardımcı komplocu, resmi blogda buna ayrıntılı olarak girdi: android-developers.blogspot.com/2011/09/…
Elliott Hughes

@ElliottHughes:% 100 katılıyorum. Apache httpclient'in kolay yöntemler ve protokolün daha soyut bir görünümünü sunduğunu inkar etmek yok, ancak java'nın yerel bağlantısının hiçbir şekilde daha az kullanışlı olmadığı. Biraz uygulamalı, httpclient kadar kullanımı kolay ve çok daha taşınabilir
Nitin Bansal

1
Aslında Google I / O 2010 - Android REST istemci uygulamaları ( youtube.com/watch?v=xHXn3Kg2IQE 57min21sec) videosuna bir göz atarsanız, en çok önerilen Apache HttpClient olduğunu görürsünüz. Virgil Dobjanschi'yi (Google'da Android Uygulama Grubunda çalışan bir yazılım mühendisi) alıntı yapıyorum "Daha basit bir uygulamaya sahip olduğu için HTTP Apache istemcisini kullanmanızı tavsiye ederim. HTTP işleminin URL bağlantı türü en verimli değil Ve bağlantıları sonlandırma şeklinin bazen ağ üzerinde olumsuz bir etkisi olabilir. "
Alan

46

Not: Android ile birlikte gelen Apache HTTP İstemcisi artık HttpURLConnection lehine kullanımdan kaldırılmıştır . Daha fazla ayrıntı için lütfen Android Geliştiricileri Blogu'na bakın.

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

Daha sonra şöyle bir web sayfası alırsınız:

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();
}

Ayrıca ayrı bir iş parçacığında çalıştırmanızı öneririz:

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..
}
}

Yanıt işleme ve POST istekleri hakkında daha fazla bilgi için belgelere bakın .


1
@Semmix Nasıl? Soru "basit bir HTTP" isteği istedi ve kodum tam olarak bunu yapıyor.
kevinc

1
İlk kod bloğunuzun Android dokümanlarından yapıştırılmış kopya olduğunu anlıyorum, ancak adam örnek / doc çöpü. readStreamtanımlanmamıştır.
Eugene K

@EugeneK Onlar, ama bu muhtemelen bu soruya cevap vermenin en basit yoludur. Android'de bir HTTP İsteğinin doğru yapılması Retrofit ve OkHttp'nin açıklanmasını içerir. Ben yeni başlayanlar sadece kötü inşa olsa bile, teknik olarak basit bir HTTP isteği yapacak bir snippet dağıtmak daha karışık olacaktır.
kevinc

12

En basit yol Volley adlı Android lib'i kullanmaktır

Volley aşağıdaki avantajları sunar:

Ağ isteklerinin otomatik programlanması. Birden çok eşzamanlı ağ bağlantısı . Standart HTTP önbellek tutarlılığı ile şeffaf disk ve bellek yanıtı önbelleği. Talep önceliklendirme desteği. İptal isteği API'sı. Tek bir isteği iptal edebilir veya iptal edilecek istek bloklarını veya kapsamlarını ayarlayabilirsiniz. Yeniden deneme ve geri çekilme için özelleştirme kolaylığı. Ağdan eşzamansız olarak getirilen verilerle kullanıcı arayüzünüzü doğru bir şekilde doldurmanızı kolaylaştıran güçlü sipariş. Hata ayıklama ve izleme araçları.

Bu kadar basit bir http / https isteği gönderebilirsiniz:

        // 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);

Bu durumda, tüm bunlar zaten Volley tarafından yapıldığından, "arka planda çalışmayı" veya "önbelleği kullanmayı" kendiniz düşünmenize gerek yoktur.


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

}

Saygılarımızla


4

Bir iplik ile:

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

Bunu bir webservisi için Gson lib kullanarak URL istemek için yaptım:

Müşteri:

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 ile sunulan bu harika yeni kütüphaneye bak :)

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

Kullanımı:

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


3

Yukarıda önerildiği gibi Voleybolu kullanın. Aşağıdakileri build.gradle'a ekleyin (Modül: app)

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

AndroidManifest.xml dosyasına aşağıdakileri ekleyin:

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

Ve size Etkinlik kodunu ekleyin:

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 istemcisinin yerini alır ve çok basittir.


2

Bu, android'de HTTP Get / POST isteği için yeni koddur. HTTPClientbenim durumumda olduğu gibi kullanılabilir ve mevcut olmayabilir.

İlk olarak build.gradle dosyasına iki bağımlılık ekleyin:

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

Sonra bu kodu yazmak ASyncTaskiçinde doBackgroundyöntemle.

 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
 }

Kod kullanımdan kaldırılabilir ve apache artık Android Platform API 28'de desteklenmez. Bu durumda, Manifest veya modül düzeyinde Gradle dosyasında apache eski özelliğini etkinleştirebilirsiniz. Ancak, OKHttp, Volley veya Retrofit ağ kütüphanesinin kullanılması tavsiye edilir.
Rahul Raina

1

Benim için en kolay yol Retrofit2 adlı kütüphaneyi kullanmak.

Sadece istek yöntemimizi, parametrelerimizi içeren bir Arayüz oluşturmamız gerekiyor ve ayrıca her istek için özel başlık yapabiliriz:

    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);    

    }

Ve en iyisi, enqueue yöntemini kullanarak senkronize olmayan bir şekilde kolayca yapabiliriz


1

Cevapların hiçbiri, günümüzde Android ve Java için çok popüler bir http istemcisi olan OkHttp ile istekleri yerine getirmenin bir yolunu tarif etmediğinden , basit bir örnek vereceğim:

//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();

Bu kütüphanenin açık avantajı, bizi bazı düşük seviyeli detaylardan soyutlaması ve onlarla etkileşim kurmak için daha kolay ve güvenli yollar sağlamasıdır. Sözdizimi de basitleştirilmiştir ve hoş kod yazılmasına izin verir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.