Programación de red de Android (4) HttpClient y HttpURLConnection

El propio Android proporciona HttpClient de Apache y HttpURLConnection de Java para la comunicación de solicitud de red. Todos admiten la comunicación de red de forma continua y todos admiten https.

1 HttpClient

La ventaja de HttpClient radica en que tratar con algunos puede requerir que el usuario inicie sesión y tenga los permisos correspondientes para acceder a la página. Por ejemplo, si necesita lidiar con Session y Cookie, debe usar HttpClient. Sus clases de implementación son DefaultHttpClient y AndroidHttpClient . Todos tienen muchas API para que llamen los desarrolladores. Sin embargo, en la versión Android 6.0 SDK, la biblioteca de clases HttpClient se ha eliminado. Si desea continuar usándola, puede agregarla a build.gradle en el módulo correspondiente:

android {
       useLibrary 'org.apache.http.legacy'
}

Ejemplos de uso:

/**
     * HttpClient的Get请求
     * @param url 请求的URL
     * @return
     */
    public static String httpClientGet(String url) {
        InputStream inStream = null;
        HttpClient httpclient = null;
        try {
            httpclient = new DefaultHttpClient();
            HttpResponse response = httpclient.execute(new HttpGet(url));
            inStream = response.getEntity().getContent();

            String result = inputStreamToString(inStream);
            return result;

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inStream != null) {
                    inStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            httpclient.getConnectionManager().shutdown();
        }
        return null;
    }

    /**
     * HttpClient的Post请求
     * @param url 请求的URL
     * @param nameValuePairs 请求参数,值的添加如:nameValuePairs.add(new BasicNameValuePair("id", "12345"));
     * @return
     */
    public static String httpClientPost(String url, List<NameValuePair> nameValuePairs) {
        InputStream inStream = null;
        HttpClient httpclient = null;

        try {
            httpclient = new DefaultHttpClient();

            HttpPost httppost = new HttpPost(url);
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs ,"UTF-8"));
            HttpResponse response = httpclient.execute(httppost);
            inStream = response.getEntity().getContent();

            String result = inputStreamToString(inStream);
            return result;

        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inStream != null) {
                    inStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            httpclient.getConnectionManager().shutdown();
        }
        return null;
    }

    /**
     * 将InputStream 格式转化为StringBuilder 格式
     * @param is
     * @return
     */
    private static String inputStreamToString(InputStream is) {
        String line = "";
        StringBuilder sb = new StringBuilder();
        try {
            BufferedReader rd = new BufferedReader(new InputStreamReader(is));
            while ((line = rd.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
// 或
//        Scanner scanner = new Scanner(is).useDelimiter("\\A");
//        return scanner.hasNext() ? scanner.next() : "";
    }

2 HttpURLConnection

Si en la situación general de solicitud de red, solo necesita una solicitud de red simple o solicitud de envío de formulario, HttpURLConnection es la mejor opción. Su API es simple y de tamaño pequeño. El mecanismo de compresión y almacenamiento en caché puede reducir efectivamente el tráfico de acceso a la red y también juega un papel importante en la mejora de la velocidad y el ahorro de energía.

Sin embargo, también debe tener en cuenta que en el pasado Android2.2 y anteriores, HttpURLConnection siempre ha tenido algunos errores demasiado problemáticos, como llamar al método close () en un InputStream legible, puede hacer que falle el grupo de conexiones Muy a menudo, la función del grupo de conexiones debe estar deshabilitada en ese momento. Sin embargo, eso también es cosa del pasado.

El error también se corrigió en la versión Android 2.3. Y agregada compresión de respuesta, agregará automáticamente el encabezado Accept-Encoding: gzip a cada solicitud enviada, y procesará los resultados de devolución correspondientes; se agregó la optimización https, usando SNI ( Indicación de nombre del servidor ) para conectarse Para que varios hosts HTTPS puedan compartir la misma dirección IP; se agregó un mecanismo para intentar reconectarse automáticamente si falla la conexión; en la versión de Android 4.0, se agregaron algunos mecanismos de almacenamiento en caché de respuestas.

Al igual que la eliminación oficial de HttpClient después de la versión Android 6.0, también se recomienda que usemos HttpURLConnection en el desarrollo, y la distribución actual de teléfonos móviles no necesita adaptarse a teléfonos antiguos antes de Android2.3.

Ejemplos de uso:

/**
     * HttpURLConnection的Get请求
     * @param urlStr
     * @return
     */
    public static String httpURLConnectionGet(String urlStr) {
        InputStream inStream = null;

        HttpURLConnection conn = null;
        try {
            URL url = new URL(urlStr);
            conn = (HttpURLConnection)url.openConnection();
//            conn.setConnectTimeout(timeOut);
//            conn.setReadTimeout(readTimeout);
            conn.setRequestMethod("GET");

            if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
                return null;
            }
            inStream = conn.getInputStream();

            String result = inputStreamToString(inStream);
            return result;

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inStream != null) {
                    inStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (conn != null) {
                conn.disconnect();
            }
        }
        return null;
    }

    public static String HttpURLConnectionPost(String urlStr, String params) {
        HttpURLConnection conn = null;
        InputStream inStream = null;
        PrintWriter printWriter = null;
        try {
            URL url = new URL(urlStr);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);                 // 是否输入参数
            //conn.setConnectTimeout(timeOut);      // 连接超时 单位毫秒
            //conn.setReadTimeout(readTimeout);     // 读取超时 单位毫秒
            conn.setUseCaches(false);               // Post 请求不能使用缓存

            // 第1种方式:使用直接输出流的方式(已知输出流的长度):
            // conn.setFixedLengthStreamingMode(输出流的固定长度);

            // 第2种方式:使用直接输出流的方式(未知输出流的长度):
            conn.setChunkedStreamingMode(5);        // 5 为块的大小

            // 第3种方式:本地缓存后一次性输出:
            // 两个函数都不指定

            conn.setRequestMethod("POST");

            // application/x-www-form-urlencoded是表单数据;application/x-javascript是json对象;application/x-javascript text/xml是xml数据
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); 
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("Content-Length", String.valueOf(params.length()));

            //PrintWriter 是文本。也就是unicode编码格式的,当然也包括汉字。
            printWriter = new PrintWriter(conn.getOutputStream());
            printWriter.write(params);
            printWriter.flush();

            // OutputStream 接受的是bytes
            // byte[] data = params.getBytes("UTF-8");
            // OutputStream outputStream = conn.getOutputStream();
            // outputStream.write(data);
            // outputStream.flush();

            //DataOutputStream 是OutputStream的一个实用类,写byte,写String都可以
            // DataOutputStream dataOutputStream = new DataOutputStream(conn.getOutputStream());
            // dataOutputStream.writeBytes(params);
            // dataOutputStream.flush();

            if(conn.getResponseCode() == HttpURLConnection.HTTP_OK){
                inStream = new BufferedInputStream(conn.getInputStream());
            } else {
                inStream = new BufferedInputStream(conn.getErrorStream());
            }

            String result = inputStreamToString(inStream);
            return result;

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
            if (printWriter != null) {
                printWriter.close();
            }
            try {
                if (inStream != null) {
                    inStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

 

Archivo de descarga de muestra :

public static boolean downloadZip(Context ctx, String urlStr) {
    InputStream is = null;
    FileOutputStream fos = null;
    boolean bRet = false;
    HttpURLConnection conn = null;
    try {
        File zipFile = getDownloadFile(ctx);  // 例如:/data/data/com.zyx.demo/mydownload/xx.zip
        URL url = new URL(urlStr);
        conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setReadTimeout(5000);
        conn.setConnectTimeout(5000);

        if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
            return false;
        }

        is = conn.getInputStream();
        fos = new FileOutputStream(zipFile);

        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = is.read(buffer)) != -1) {
            fos.write(buffer, 0, len);
        }
        bRet = true;
    } catch (Exception e) {
    } finally {
        try {
            if (is != null) {
                is.close();
            }
            if (fos != null) {
                fos.close();
            }
            if (conn != null) {
                conn.disconnect();
            }
        } catch (Exception e) {
        }
    }
    return bRet;
}

public static File getDownloadFile(Context ctx) {
    try {
        String dexDir = ctx.getDir("mydownload", Context.MODE_PRIVATE).getAbsolutePath();
        String path = dexDir + File.separator + "xx.zip";
        return new File(path);
    } catch (Exception e) {
    }
    return null;
}

 

106 artículos originales publicados · elogiados 37 · 80,000 visitas

Supongo que te gusta

Origin blog.csdn.net/lyz_zyx/article/details/96328449
Recomendado
Clasificación