在Android开发中网络请求是最常用的操作之一, Android SDK中对HTTP(超文本传输协议)也提供了很好的支持,这里包括两种接口:
1、HttpURLConnection,可以实现简单的基于URL请求、响应功能;
2、HttpClient,使用起来更方面更强大,使用方便,但是不易于扩展(不推荐使用)。
但在android API23的SDK中Google将HttpClient移除了。Google建议使用httpURLconnection进行网络访问操作。
HttpURLconnection是基于http协议的,支持get,post,put,delete等各种请求方式,最常用的就是get和post,下面针对这两种请求方式进行讲解。
以下是自己对HttpURLconnection进行了封装。
HttpUtils代码:
public class HttpUtils { private static ExecutorService threadPool = Executors.newCachedThreadPool(); private static final int HTTP_CONNECT_TIME=5000; private static final int HTTP_READ_TIME=10000; /** * GET请求返回数据会解析成字符串String * @param context context * @param urlPath 请求的路径 * @param listener listener */ public static void doGet(final Context context, final String urlPath, final StringCallbackListener listener) { threadPool.execute(new Runnable() { @Override public void run() { URL url; HttpURLConnection httpURLConnection = null; try { // 根据URL地址创建URL对象 url = new URL(urlPath); // 获取HttpURLConnection对象 httpURLConnection = ( HttpURLConnection ) url.openConnection(); // 设置请求方式,默认为GET httpURLConnection.setRequestMethod("GET"); // 设置连接超时 httpURLConnection.setConnectTimeout(HTTP_CONNECT_TIME); // 设置读取超时 httpURLConnection.setReadTimeout(HTTP_READ_TIME); // 响应码为200表示成功 if ( httpURLConnection.getResponseCode() == 200 ) { // 获取网络的输入流 InputStream is = httpURLConnection.getInputStream(); BufferedReader bf = new BufferedReader(new InputStreamReader(is, "UTF-8")); StringBuffer buffer = new StringBuffer(); String line = ""; while ( (line = bf.readLine()) != null ) { buffer.append(line); } is.close(); bf.close(); new ResponseCall(context, listener).doSuccess(buffer.toString()); } else { new ResponseCall(context, listener).doFail( new NetworkErrorException("response error code:" + httpURLConnection.getResponseCode())); } } catch ( MalformedURLException e ) { if ( listener != null ) { new ResponseCall(context, listener).doFail(e); } } catch ( IOException e ) { if ( listener != null ) { new ResponseCall(context, listener).doFail(e); } } finally { if ( httpURLConnection != null ) { // 释放资源 httpURLConnection.disconnect(); } } } }); } /** * GET请求返回数据会解析成byte[]数组 * @param context context * @param urlPath 请求的url * @param listener 回调监听 */ public static void doGet(final Context context, final String urlPath, final BytesCallbackListener listener) { threadPool.execute(new Runnable() { @Override public void run() { URL url = null; HttpURLConnection httpURLConnection = null; try { // 根据URL地址创建URL对象 url = new URL(urlPath); // 获取HttpURLConnection对象 httpURLConnection = ( HttpURLConnection ) url.openConnection(); // 设置请求方式,默认为GET httpURLConnection.setRequestMethod("GET"); // 设置连接超时 httpURLConnection.setConnectTimeout(HTTP_CONNECT_TIME); // 设置读取超时 httpURLConnection.setReadTimeout(HTTP_READ_TIME); // 响应码为200表示成功,否则失败。 if ( httpURLConnection.getResponseCode() != 200 ) { new ResponseCall(context, listener).doFail( new NetworkErrorException("response error code:" + httpURLConnection.getResponseCode())); } else { // 获取网络的输入流 InputStream is = httpURLConnection.getInputStream(); // 读取输入流中的数据 BufferedInputStream bis = new BufferedInputStream(is); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] bytes = new byte[1024]; int len = -1; while ( (len = bis.read(bytes)) != -1 ) { baos.write(bytes, 0, len); } bis.close(); is.close(); new ResponseCall(context, listener).doSuccess(baos.toByteArray()); } } catch ( MalformedURLException e ) { if ( listener != null ) { new ResponseCall(context, listener).doFail(e); } } catch ( IOException e ) { if ( listener != null ) { new ResponseCall(context, listener).doFail(e); } } finally { if ( httpURLConnection != null ) { httpURLConnection.disconnect(); } } } }); } /** * GET请求返回数据会解析成字符串 String * @param context context * @param urlPath 请求的路径 * @param listener 回调监听 * @param params 参数列表 */ public static void doPost(final Context context, final String urlPath, final StringCallbackListener listener, final Map<String, Object> params) { final StringBuffer buffer = new StringBuffer(); for (String key : params.keySet()) { if(buffer.length()!=0){ buffer.append("&"); } buffer.append(key).append("=").append(params.get(key)); } threadPool.execute(new Runnable() { @Override public void run() { URL url; HttpURLConnection httpURLConnection = null; try { url = new URL(urlPath); httpURLConnection = ( HttpURLConnection ) url.openConnection(); httpURLConnection.setRequestProperty("accept", "*/*"); httpURLConnection.setRequestProperty("connection", "Keep-Alive"); httpURLConnection.setRequestProperty("Content-Length", String .valueOf(buffer.length())); httpURLConnection.setRequestMethod("POST"); httpURLConnection.setConnectTimeout(HTTP_CONNECT_TIME); httpURLConnection.setReadTimeout(HTTP_READ_TIME); // 设置运行输入 httpURLConnection.setDoInput(true); // 设置运行输出 httpURLConnection.setDoOutput(true); PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream()); // 发送请求参数 printWriter.write(buffer.toString()); // flush输出流的缓冲 printWriter.flush(); printWriter.close(); if ( httpURLConnection.getResponseCode() == 200 ) { // 获取网络的输入流 InputStream is = httpURLConnection.getInputStream(); BufferedReader bf = new BufferedReader(new InputStreamReader(is, "UTF-8")); //最好在将字节流转换为字符流的时候 进行转码 StringBuffer buffer = new StringBuffer(); String line = ""; while ( (line = bf.readLine()) != null ) { buffer.append(line); } bf.close(); is.close(); new ResponseCall(context, listener).doSuccess(buffer.toString()); } else { new ResponseCall(context, listener).doFail( new NetworkErrorException("response error code:" + httpURLConnection.getResponseCode())); } } catch ( MalformedURLException e ) { if ( listener != null ) { new ResponseCall(context, listener).doFail(e); } } catch ( IOException e ) { if ( listener != null ) { new ResponseCall(context, listener).doFail(e); } } finally { if ( httpURLConnection != null ) { httpURLConnection.disconnect(); } } } }); } /** * GET请求 返回数据会解析成Byte[]数组 * @param context context * @param urlPath 请求的路径 * @param listener 回调监听 * @param params 参数列表 */ public static void doPost(final Context context, final String urlPath, final BytesCallbackListener listener, final Map<String, Object> params) { final StringBuffer buffer = new StringBuffer(); for (String key : params.keySet()) { if(buffer.length()!=0){ buffer.append("&"); } buffer.append(key).append("=").append(params.get(key)); } threadPool.execute(new Runnable() { @Override public void run() { URL url; HttpURLConnection httpURLConnection = null; try { url = new URL(urlPath); httpURLConnection = ( HttpURLConnection ) url.openConnection(); httpURLConnection.setRequestProperty("accept", "*/*"); httpURLConnection.setRequestProperty("connection", "Keep-Alive"); httpURLConnection.setRequestProperty("Content-Length", String .valueOf(buffer.length())); httpURLConnection.setRequestMethod("POST"); httpURLConnection.setConnectTimeout(HTTP_CONNECT_TIME); httpURLConnection.setReadTimeout(HTTP_READ_TIME); // 设置运行输入 httpURLConnection.setDoInput(true); // 设置运行输出 httpURLConnection.setDoOutput(true); PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream()); // 发送请求参数 printWriter.write(buffer.toString()); // flush输出流的缓冲 printWriter.flush(); printWriter.close(); if ( httpURLConnection.getResponseCode() == 200 ) { // 获取网络的输入流 InputStream is = httpURLConnection.getInputStream(); // 读取输入流中的数据 BufferedInputStream bis = new BufferedInputStream(is); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] bytes = new byte[1024]; int len = -1; while ( (len = bis.read(bytes)) != -1 ) { baos.write(bytes, 0, len); } bis.close(); is.close(); // 响应的数据 new ResponseCall(context, listener).doSuccess(baos.toByteArray()); } else { new ResponseCall(context, listener).doFail( new NetworkErrorException("response error code:" + httpURLConnection.getResponseCode())); } } catch ( MalformedURLException e ) { if ( listener != null ) { new ResponseCall(context, listener).doFail(e); } } catch ( IOException e ) { if ( listener != null ) { new ResponseCall(context, listener).doFail(e); } } finally { if ( httpURLConnection != null ) { httpURLConnection.disconnect(); } } } }); } }
ResponseCall<T> 代码:
public class ResponseCall<T> { private static final int FAIL = 0; private static final int SUCCESS = 1; private Handler mHandler; public ResponseCall(Context context, final BytesCallbackListener listener) { Looper looper = context.getMainLooper(); mHandler = new Handler(looper) { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if ( msg.what == FAIL ) { //成功 listener.onSuccess(( byte[] ) msg.obj); } else if ( msg.what == SUCCESS ) { //失败 listener.onError(( Exception ) msg.obj); } } }; } public ResponseCall(Context context, final StringCallbackListener listener) { Looper looper = context.getMainLooper(); mHandler = new Handler(looper) { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if ( msg.what == FAIL ) { //成功 listener.onSuccess(msg.obj.toString()); } else if ( msg.what == SUCCESS ) { //失败 listener.onError(( Exception ) msg.obj); } } }; } public void doSuccess(T response) { Message message = Message.obtain(); message.obj = response; message.what = FAIL; mHandler.sendMessage(message); } public void doFail(Exception e) { Message message = Message.obtain(); message.obj = e; message.what = SUCCESS; mHandler.sendMessage(message); } }
BytesCallbackListener:
public interface BytesCallbackListener { // 网络请求成功 void onSuccess(byte[] response); // 网络请求失败 void onError(Exception e); }
StringCallbackListener:
public interface StringCallbackListener { // 网络请求成功 void onSuccess(String response); // 网络请求失败 void onError(Exception e); }