写在前面:

  最近准备一个关于Android的比赛。由于赛项要求,不得使用第三方工具、框架;故最近来温习一下Google官方提供的原始API的使用。

  说实话,用惯了第三方的库,再回过头来用原生的api的确令人觉得麻烦,不过也不能仅仅依赖于各种层出不穷的框架和库,掌握相对底层的核心点,才是竞争力的来源。并且用了第三方的库之后再来看原生,不经意间就会有好的思路产生。

  那么,今天就来简单介绍一下HttpUrlConnect的基本使用,和笔者自己做的一个小的工具类封装。

先来学习原生的使用:

  Ps:  解释以注释形式写在代码中

  * GET请求

  1. new Thread(new Runnable() {
  2. @Override
  3. public void run() {
  4. //接口地址
  5. String url_path = "http://223.111.182.5:8080/logistics/goods/myOffer";
  6. try{
  7. //使用该地址创建一个 URL 对象
  8. URL url = new URL(url_path);
  9. //使用创建的URL对象的openConnection()方法创建一个HttpURLConnection对象
  10. HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
  11. /**
  12. * 设置HttpURLConnection对象的参数
  13. */
  14. // 设置请求方法为 GET 请求
  15. httpURLConnection.setRequestMethod("GET");
  16. //使用输入流
  17. httpURLConnection.setDoInput(true);
  18. //GET 方式,不需要使用输出流
  19. httpURLConnection.setDoOutput(false);
  20. //设置超时
  21. httpURLConnection.setConnectTimeout(10000);
  22. httpURLConnection.setReadTimeout(1000);
  23. //连接
  24. httpURLConnection.connect();
  25. //还有很多参数设置 请自行查阅
  26.  
  27. //连接后,创建一个输入流来读取response
  28. BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(),"utf-8"));
  29. String line = "";
  30. StringBuilder stringBuilder = new StringBuilder();
  31. String response = "";
  32. //每次读取一行,若非空则添加至 stringBuilder
  33. while((line = bufferedReader.readLine()) != null){
  34. stringBuilder.append(line);
  35. }
  36. //读取所有的数据后,赋值给 response
  37. response = stringBuilder.toString().trim();
  38. Utils.log(" 打印响应 " + response);
  39. final String finalResponse = response;
  40. //切换到ui线程更新ui
  41. runOnUiThread(new Runnable() {
  42. @Override
  43. public void run() {
  44. result.setText(finalResponse);
  45. }
  46. });
  47. bufferedReader.close();
  48. httpURLConnection.disconnect();
  49. }catch (Exception e){
  50. e.printStackTrace();
  51. }
  52. }
  53. }).start();

  * POST请求

  1. new Thread(new Runnable() {
  2. //创建HttpURLConnection变量
  3. HttpURLConnection httpURLConnection = null;
  4. //创建PrintWriter变量,用于向HttpURLConnection写入请求参数
  5. PrintWriter printWriter = null;
  6. //创建BufferedReader,来接收相应数据流
  7. BufferedReader bufferedReader = null;
  8. //定义缓冲
  9. StringBuilder stringBuilder = new StringBuilder();
  10. //定义line读取一行数据
  11. String line = "";
  12. //定义接口地址
  13. String url_path = "http://xxx.xxx.xxx.xxx:8080/logistics/goods/bidCount";
  14. //模拟参数
  15. String para = "goodId=14";
  16. String response = "";
  17. @Override
  18. public void run() {
  19. try{
  20. URL url = null;
  21. if(url_path.equals("")){
  22. return;
  23. }
  24. //使用接口地址初始化URL对象
  25. url = new URL(url_path);
  26. //使用URL对象创建HttpURLConnection对象
  27. httpURLConnection = (HttpURLConnection) url.openConnection();
  28. //设置相应参数
  29. httpURLConnection.setDoInput(true);
  30. httpURLConnection.setDoOutput(true); //可以创建输出流,将请求参数写入
  31. httpURLConnection.setRequestMethod("POST"); //请求方式为POST
  32. //将请求参数写入连接的输出流
  33. printWriter = new PrintWriter(httpURLConnection.getOutputStream());
  34. printWriter.print(para);
  35. printWriter.flush();
  36. //获取响应结果
  37. bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(),"utf-8"));
  38. while ((line = bufferedReader.readLine()) != null){
  39. stringBuilder.append(line);
  40. }
  41. response = stringBuilder.toString().trim();
  42. //切换主线程更新ui
  43. runOnUiThread(new Runnable() {
  44. @Override
  45. public void run() {
  46. result.setText(response);
  47. }
  48. });
  49. }catch (Exception e){
  50. e.printStackTrace();
  51. }finally {
  52. try{
  53. /**
  54. * 关闭连接/流
  55. */
  56. if(printWriter != null){
  57. printWriter.close();
  58. }
  59. if(bufferedReader != null){
  60. bufferedReader.close();
  61. }
  62. if(httpURLConnection != null){
  63. httpURLConnection.disconnect();
  64. }
  65. }catch (Exception e){
  66. e.printStackTrace();
  67. }
  68. }
  69. }
  70. }).start();

下面贴一个自己写的一个Post请求工具类:

  Ps:为什么不封装的更完善些呢?比如支持支持Get请求、支持自定义Http头部各参数设置,异步消息部分采用Handle或AsynTask。其实刚刚说的这些包括还没有想到的,都可以添加上去,只是笔者时间紧迫,所以以下的工具类只提供Post方式的请求。

  工具类支持:

    •   自定义参数(传参时,只要传入相对应的map)
    •   支持接口回调,在回调方法内写结果处理逻辑
    •   简单的线程控制,开发者不需要手动实现线程切换
    •   简单易用的API

  下面贴工具类代码,和简单的使用方法:

  1. /**
  2. * 作者:LiChangXin
  3. * Created by haiyang on 2018/1/25.
  4. * 简介:
  5. * 1.自定义参数(传参时,只要传入相对应的map)
  6. * 2.支持接口回调,在回调方法内写结果处理逻辑
  7. * 3.简单的线程控制,开发者不需要手动实现线程切换
  8. * 4.简单易用的API
  9. */
  10.  
  11. public class XykjHttpPost extends Thread{
  12. /**
  13. * 通过构造函数
  14. * 赋值:
  15. * url - 接口地址
  16. * form - 请求参数(map)
  17. * xykjHttpCall - 回调接口
  18. * mactivity - 基于activity的runOnUiThread()方法的线程控制
  19. */
  20. private String url = "";
  21. private Map<String,String> form;
  22. private XykjHttpCall xykjHttpCall = null;
  23. private Activity mactivity;
  24. //下面这些 与之前的例子相同
  25. private HttpURLConnection connection = null;
  26. private PrintWriter pw = null;
  27. private BufferedReader bufferedReader = null;
  28. private String line = null;
  29. private StringBuilder response_cache = new StringBuilder();
  30. private String response = null;
  31. private String parameter = null;
  32. //构造函数
  33. public XykjHttpPost(XykjHttpCall xykjHttpCall,String url_p, Map<String,String> form_p,
  34. Activity activity){
  35. url = url_p;
  36. form = form_p;
  37. this.xykjHttpCall = xykjHttpCall;
  38. mactivity = activity;
  39. }
  40.  
  41. @Override
  42. public void run() {
  43. Utils.log("XYKJHTTPPOST : " + "Thread@run() 方法开始执行");
  44. try{
  45. if(url.equals("") || url == null){
  46. //若url为空,结束执行
  47. Utils.log("XYKJHTTPPOST : " + "无请求参数");
  48. return;
  49. }
  50. URL url_path = new URL(url.trim());
  51. connection = (HttpURLConnection) url_path.openConnection();
  52. connection.setDoOutput(true);
  53. connection.setDoInput(true);
  54. connection.setUseCaches(false);
  55. connection.setRequestMethod("POST");
  56. //获取连接
  57. connection.connect();
  58. if(!form.isEmpty() && form != null){
  59. //获取连接输出流,并写入表单参数
  60. pw = new PrintWriter(connection.getOutputStream());
  61. parameter = formDataConnect(form);
  62. pw.print(parameter);
  63. pw.flush();
  64. }
  65. //获取响应 输入流
  66. bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
  67. while ((line = bufferedReader.readLine()) != null){
  68. response_cache.append(line);
  69. }
  70. response = response_cache.toString().trim();
  71. Utils.log("XYKJHTTPPOST : RESPONSE -> " + response);
  72. mactivity.runOnUiThread(new Runnable() {
  73. @Override
  74. public void run() {
  75. if(response != null && !response.equals("")){
  76. xykjHttpCall.success(response);
  77. }else {
  78. xykjHttpCall.error("Response为空");
  79. }
  80. }
  81. });
  82. }catch (Exception e){
  83. mactivity.runOnUiThread(new Runnable() {
  84. @Override
  85. public void run() {
  86. xykjHttpCall.error("XYKJHTTPPOST : 网络请求/解析异常");
  87. }
  88. });
  89. Utils.log("XYKJHTTPPOST : 网络请求/解析异常");
  90. e.printStackTrace();
  91. }finally {
  92. try{
  93. if(pw != null){
  94. pw.close();
  95. }
  96. if(bufferedReader != null){
  97. bufferedReader.close();
  98. }
  99. if(connection != null){
  100. connection.disconnect();
  101. }
  102. }catch (Exception e){
  103. mactivity.runOnUiThread(new Runnable() {
  104. @Override
  105. public void run() {
  106. xykjHttpCall.error("XYKJHTTPPOST : 关闭连接/流异常");
  107. }
  108. });
  109. Utils.log("XYKJHTTPPOST : 关闭连接/流异常");
  110. e.printStackTrace();
  111. }
  112. }
  113. }
  114.  
  115. /**
  116. * 参数转换函数
  117. * map -> http[post] 参数
  118. * @param form_data
  119. * @return
  120. */
  121. public String formDataConnect(Map<String,String> form_data){
  122. StringBuilder url_form = new StringBuilder();
  123. //遍历map,按照url参数形式拼接
  124. for(String key:form_data.keySet()){
  125. if(url_form.length() != 0){
  126. //从第二个参数开始,每个参数key、value前添加 & 符号
  127. url_form.append("&");
  128. }
  129. url_form.append(key).append("=").append(form_data.get(key));
  130. }
  131. return url_form.toString();
  132. }
  133.  
  134. /**
  135. * 定义回调接口
  136. */
  137. public interface XykjHttpCall {
  138. void success(String response);
  139. void error(String error_message);
  140. }
  141.  
  142. /**
  143. * 线程启动
  144. * 执行请求
  145. */
  146. public void request(){
  147. this.start();
  148. }
  149.  
  150. }

* 使用方法:

  先上业务场景,是一个用户的登录操作,收集 手机号码和密码 后进行post请求验证。

最后调用该对象的request()方法,即可启动post请求。

* 效果:

  

   Ok,今天的营养目标达成。

  有什么问题或者有好的想法的可以在评论里留言,笔者会在第一时间解答。

  未来的话,如果笔者继续搞Android,会慢慢来丰富这个工具类,届时会开源到Github上,虽然水平一般,但开源精神还是可赞的嘛

Android回顾系列——之HttpUrlConnect的使用的更多相关文章

  1. Android拓展系列(11)--打造Windows下便携的Android源码阅读环境

    因为EXT和NTFS格式的差异,我一直对于windows下阅读Android源码感到不满. 前几天,想把最新的android5.0的源码下下来研究一下,而平时日常使用的又是windows环境,于是专门 ...

  2. Android学习系列(37)--App调试内存泄露之Context篇(下)

    接着<Android学习系列(36)--App调试内存泄露之Context篇(上)>继续分析. 5. AsyncTask对象 我N年前去盛大面过一次试,当时面试官极力推荐我使用AsyncT ...

  3. [转]Android Studio系列教程六--Gradle多渠道打包

    转自:http://www.stormzhang.com/devtools/2015/01/15/android-studio-tutorial6/ Android Studio系列教程六--Grad ...

  4. Android UI系列-----时间、日期、Toasts和进度条Dialog

    您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态. 如果文章内容对您有帮助, 不要忘记点击右下角的 推荐按钮 来支持一下哦 如果您对文章内 ...

  5. 【Android进阶系列教程】前言

    起因 因为初学Android的时候还没有写博客的意识,现在Android的门是入了,正在进阶的道路上行走,但是就这一路也走了不少的弯路.我想,总得来说Android入门还是比较容易的,网络资源比较丰富 ...

  6. Android Studio系列教程六--Gradle多渠道打包

    Android Studio系列教程六--Gradle多渠道打包 2015 年 01 月 15 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzh ...

  7. Android Studio系列教程五--Gradle命令详解与导入第三方包

    Android Studio系列教程五--Gradle命令详解与导入第三方包 2015 年 01 月 05 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://s ...

  8. Android Studio系列教程四--Gradle基础

    Android Studio系列教程四--Gradle基础 2014 年 12 月 18 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzhang ...

  9. Android Studio系列教程三--快捷键

    Android Studio系列教程三--快捷键 2014 年 12 月 09 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzhang.com/ ...

随机推荐

  1. avro 1.8.2 (js)

    5月15日发布的avro 1.8.2 已经包含了js版代码. 清华大学镜像地址: https://mirrors.tuna.tsinghua.edu.cn/apache/avro/avro-1.8.2 ...

  2. Python 阿里大于发送手机验证码

    1.安装阿里大于的包 pip install top 2.事例脚本 # -*- coding: utf-8 -*- import top.api appkey = '2353xxxx' secret ...

  3. Zabbix 单位换算

    直接举一例子,然后再举一反三: 如图: 单位B 则基数为1024(倍数) 我性能参数为KB单位,我们则把单位转换成和我们计数器 保持一致的单位即可,一致后,zabbix 后面会自己准换成自己想要的显示 ...

  4. golang 用tar打包文件或文件夹

    打包文件用到了tar包,其中tar包的用法可以参考API golang提供了个函数用来遍历文件夹 filepath.Walk 函数具体描述如下: func Walk(root string, walk ...

  5. vue2.0 关于Vue实例的生命周期

    什么是生命周期 Vue实例有一个完整的生命周期,也就是从开始创建.初始化数据.编译模板.挂载Dom.渲染→更新→渲染.卸载等一系列过程,我们称这是Vue的生命周期.通俗说就是Vue实例从创建到销毁的过 ...

  6. Hadoop之Hive篇

    想了解Hadoop整体结构及各框架角色建议飞入这篇文章,写的很好:http://www.open-open.com/lib/view/open1385685943484.html .以下文章是本人参考 ...

  7. zxing .net 多种条码格式的生成

    下载地址:http://zxingnet.codeplex.com/ zxing.net是.net平台下编解条形码和二维码的工具,使用非常方便. 本文主要说明一下多种类型条码的生成. 适用的场景,标签 ...

  8. 第一章:Python基础の快速认识基本语法

    本課主題 第一个 Hello World 程序实战 用户输入实战 模块介紹 变量介绍 格式化介紹 条件判断介紹和操作实战 for 循环介紹和操作实战 作业需求 Python 第一个 Hello Wor ...

  9. Unity3d 协程

    参考文章: http://blog.csdn.net/onafioo/article/details/48979939 http://www.cnblogs.com/zhaoqingqing/p/37 ...

  10. 基于opencv和mfc的摄像头采集代码(GOMFCTemplate2)持续更新

            编写带界面的图像处理程序,选择opencv+mfc是一种很好的选择:在读取摄像头数据方面,网上的方法很多,其中shiqiyu的camerads的方法是较好的.       基于现有资料 ...