最近准备一个关于Android的比赛。因为赛项要求,不得使用第三方工具、框架;故最近来温习一下Google官方提供的原始API的使用。api
说实话,用惯了第三方的库,再回过头来用原生的api的确使人以为麻烦,不过也不能仅仅依赖于各类层出不穷的框架和库,掌握相对底层的核心点,才是竞争力的来源。而且用了第三方的库以后再来看原生,不经意间就会有好的思路产生。网络
那么,今天就来简单介绍一下HttpUrlConnect的基本使用,和笔者本身作的一个小的工具类封装。app
Ps: 解释以注释形式写在代码中框架
* GET请求异步
new Thread(new Runnable() { @Override public void run() { //接口地址 String url_path = "http://223.111.182.5:8080/logistics/goods/myOffer"; try{ //使用该地址建立一个 URL 对象 URL url = new URL(url_path); //使用建立的URL对象的openConnection()方法建立一个HttpURLConnection对象 HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection(); /** * 设置HttpURLConnection对象的参数 */ // 设置请求方法为 GET 请求 httpURLConnection.setRequestMethod("GET"); //使用输入流 httpURLConnection.setDoInput(true); //GET 方式,不须要使用输出流 httpURLConnection.setDoOutput(false); //设置超时 httpURLConnection.setConnectTimeout(10000); httpURLConnection.setReadTimeout(1000); //链接 httpURLConnection.connect(); //还有不少参数设置 请自行查阅 //链接后,建立一个输入流来读取response BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(),"utf-8")); String line = ""; StringBuilder stringBuilder = new StringBuilder(); String response = ""; //每次读取一行,若非空则添加至 stringBuilder while((line = bufferedReader.readLine()) != null){ stringBuilder.append(line); } //读取全部的数据后,赋值给 response response = stringBuilder.toString().trim(); Utils.log(" 打印响应 " + response); final String finalResponse = response; //切换到ui线程更新ui runOnUiThread(new Runnable() { @Override public void run() { result.setText(finalResponse); } }); bufferedReader.close(); httpURLConnection.disconnect(); }catch (Exception e){ e.printStackTrace(); } } }).start();
* POST请求ide
new Thread(new Runnable() { //建立HttpURLConnection变量 HttpURLConnection httpURLConnection = null; //建立PrintWriter变量,用于向HttpURLConnection写入请求参数 PrintWriter printWriter = null; //建立BufferedReader,来接收相应数据流 BufferedReader bufferedReader = null; //定义缓冲 StringBuilder stringBuilder = new StringBuilder(); //定义line读取一行数据 String line = ""; //定义接口地址 String url_path = "http://xxx.xxx.xxx.xxx:8080/logistics/goods/bidCount"; //模拟参数 String para = "goodId=14"; String response = ""; @Override public void run() { try{ URL url = null; if(url_path.equals("")){ return; } //使用接口地址初始化URL对象 url = new URL(url_path); //使用URL对象建立HttpURLConnection对象 httpURLConnection = (HttpURLConnection) url.openConnection(); //设置相应参数 httpURLConnection.setDoInput(true); httpURLConnection.setDoOutput(true); //能够建立输出流,将请求参数写入 httpURLConnection.setRequestMethod("POST"); //请求方式为POST //将请求参数写入链接的输出流 printWriter = new PrintWriter(httpURLConnection.getOutputStream()); printWriter.print(para); printWriter.flush(); //获取响应结果 bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(),"utf-8")); while ((line = bufferedReader.readLine()) != null){ stringBuilder.append(line); } response = stringBuilder.toString().trim(); //切换主线程更新ui runOnUiThread(new Runnable() { @Override public void run() { result.setText(response); } }); }catch (Exception e){ e.printStackTrace(); }finally { try{ /** * 关闭链接/流 */ if(printWriter != null){ printWriter.close(); } if(bufferedReader != null){ bufferedReader.close(); } if(httpURLConnection != null){ httpURLConnection.disconnect(); } }catch (Exception e){ e.printStackTrace(); } } } }).start();
Ps:为何不封装的更完善些呢?好比支持支持Get请求、支持自定义Http头部各参数设置,异步消息部分采用Handle或AsynTask。其实刚刚说的这些包括尚未想到的,均可以添加上去,只是笔者时间紧迫,因此如下的工具类只提供Post方式的请求。函数
工具类支持:工具
下面贴工具类代码,和简单的使用方法:post
/** * 做者:LiChangXin * Created by haiyang on 2018/1/25. * 简介: * 1.自定义参数(传参时,只要传入相对应的map) * 2.支持接口回调,在回调方法内写结果处理逻辑 * 3.简单的线程控制,开发者不须要手动实现线程切换 * 4.简单易用的API */ public class XykjHttpPost extends Thread{ /** * 经过构造函数 * 赋值: * url - 接口地址 * form - 请求参数(map) * xykjHttpCall - 回调接口 * mactivity - 基于activity的runOnUiThread()方法的线程控制 */ private String url = ""; private Map<String,String> form; private XykjHttpCall xykjHttpCall = null; private Activity mactivity; //下面这些 与以前的例子相同 private HttpURLConnection connection = null; private PrintWriter pw = null; private BufferedReader bufferedReader = null; private String line = null; private StringBuilder response_cache = new StringBuilder(); private String response = null; private String parameter = null; //构造函数 public XykjHttpPost(XykjHttpCall xykjHttpCall,String url_p, Map<String,String> form_p, Activity activity){ url = url_p; form = form_p; this.xykjHttpCall = xykjHttpCall; mactivity = activity; } @Override public void run() { Utils.log("XYKJHTTPPOST : " + "Thread@run() 方法开始执行"); try{ if(url.equals("") || url == null){ //若url为空,结束执行 Utils.log("XYKJHTTPPOST : " + "无请求参数"); return; } URL url_path = new URL(url.trim()); connection = (HttpURLConnection) url_path.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setUseCaches(false); connection.setRequestMethod("POST"); //获取链接 connection.connect(); if(!form.isEmpty() && form != null){ //获取链接输出流,并写入表单参数 pw = new PrintWriter(connection.getOutputStream()); parameter = formDataConnect(form); pw.print(parameter); pw.flush(); } //获取响应 输入流 bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream())); while ((line = bufferedReader.readLine()) != null){ response_cache.append(line); } response = response_cache.toString().trim(); Utils.log("XYKJHTTPPOST : RESPONSE -> " + response); mactivity.runOnUiThread(new Runnable() { @Override public void run() { if(response != null && !response.equals("")){ xykjHttpCall.success(response); }else { xykjHttpCall.error("Response为空"); } } }); }catch (Exception e){ mactivity.runOnUiThread(new Runnable() { @Override public void run() { xykjHttpCall.error("XYKJHTTPPOST : 网络请求/解析异常"); } }); Utils.log("XYKJHTTPPOST : 网络请求/解析异常"); e.printStackTrace(); }finally { try{ if(pw != null){ pw.close(); } if(bufferedReader != null){ bufferedReader.close(); } if(connection != null){ connection.disconnect(); } }catch (Exception e){ mactivity.runOnUiThread(new Runnable() { @Override public void run() { xykjHttpCall.error("XYKJHTTPPOST : 关闭链接/流异常"); } }); Utils.log("XYKJHTTPPOST : 关闭链接/流异常"); e.printStackTrace(); } } } /** * 参数转换函数 * map -> http[post] 参数 * @param form_data * @return */ public String formDataConnect(Map<String,String> form_data){ StringBuilder url_form = new StringBuilder(); //遍历map,按照url参数形式拼接 for(String key:form_data.keySet()){ if(url_form.length() != 0){ //从第二个参数开始,每一个参数key、value前添加 & 符号 url_form.append("&"); } url_form.append(key).append("=").append(form_data.get(key)); } return url_form.toString(); } /** * 定义回调接口 */ public interface XykjHttpCall { void success(String response); void error(String error_message); } /** * 线程启动 * 执行请求 */ public void request(){ this.start(); } }
* 使用方法:学习
先上业务场景,是一个用户的登陆操做,收集 手机号码和密码 后进行post请求验证。
最后调用该对象的request()方法,便可启动post请求。
* 效果:
Ok,今天的养分目标达成。
有什么问题或者有好的想法的能够在评论里留言,笔者会在第一时间解答。
将来的话,若是笔者继续搞Android,会慢慢来丰富这个工具类,届时会开源到Github上,虽然水平通常,但开源精神仍是可赞的嘛😀