Android回顾系列——之HttpUrlConnect的使用
写在前面:
最近准备一个关于Android的比赛。由于赛项要求,不得使用第三方工具、框架;故最近来温习一下Google官方提供的原始API的使用。
说实话,用惯了第三方的库,再回过头来用原生的api的确令人觉得麻烦,不过也不能仅仅依赖于各种层出不穷的框架和库,掌握相对底层的核心点,才是竞争力的来源。并且用了第三方的库之后再来看原生,不经意间就会有好的思路产生。
那么,今天就来简单介绍一下HttpUrlConnect的基本使用,和笔者自己做的一个小的工具类封装。
先来学习原生的使用:
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请求
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();
下面贴一个自己写的一个Post请求工具类:
Ps:为什么不封装的更完善些呢?比如支持支持Get请求、支持自定义Http头部各参数设置,异步消息部分采用Handle或AsynTask。其实刚刚说的这些包括还没有想到的,都可以添加上去,只是笔者时间紧迫,所以以下的工具类只提供Post方式的请求。
工具类支持:
- 自定义参数(传参时,只要传入相对应的map)
- 支持接口回调,在回调方法内写结果处理逻辑
- 简单的线程控制,开发者不需要手动实现线程切换
- 简单易用的API
下面贴工具类代码,和简单的使用方法:
/**
* 作者: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上,虽然水平一般,但开源精神还是可赞的嘛
Android回顾系列——之HttpUrlConnect的使用的更多相关文章
- Android拓展系列(11)--打造Windows下便携的Android源码阅读环境
因为EXT和NTFS格式的差异,我一直对于windows下阅读Android源码感到不满. 前几天,想把最新的android5.0的源码下下来研究一下,而平时日常使用的又是windows环境,于是专门 ...
- Android学习系列(37)--App调试内存泄露之Context篇(下)
接着<Android学习系列(36)--App调试内存泄露之Context篇(上)>继续分析. 5. AsyncTask对象 我N年前去盛大面过一次试,当时面试官极力推荐我使用AsyncT ...
- [转]Android Studio系列教程六--Gradle多渠道打包
转自:http://www.stormzhang.com/devtools/2015/01/15/android-studio-tutorial6/ Android Studio系列教程六--Grad ...
- Android UI系列-----时间、日期、Toasts和进度条Dialog
您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态. 如果文章内容对您有帮助, 不要忘记点击右下角的 推荐按钮 来支持一下哦 如果您对文章内 ...
- 【Android进阶系列教程】前言
起因 因为初学Android的时候还没有写博客的意识,现在Android的门是入了,正在进阶的道路上行走,但是就这一路也走了不少的弯路.我想,总得来说Android入门还是比较容易的,网络资源比较丰富 ...
- Android Studio系列教程六--Gradle多渠道打包
Android Studio系列教程六--Gradle多渠道打包 2015 年 01 月 15 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzh ...
- Android Studio系列教程五--Gradle命令详解与导入第三方包
Android Studio系列教程五--Gradle命令详解与导入第三方包 2015 年 01 月 05 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://s ...
- Android Studio系列教程四--Gradle基础
Android Studio系列教程四--Gradle基础 2014 年 12 月 18 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzhang ...
- Android Studio系列教程三--快捷键
Android Studio系列教程三--快捷键 2014 年 12 月 09 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzhang.com/ ...
随机推荐
- 7.nginx伪静态规则
网上收集的一些常用的,要用的时候就仿照一下,或直接拿来用. WordPress伪静态规则 location / { index index.html index.php; if (-f $reques ...
- centos7 编译ntopng源码
先安装编译所需的开发工具 yum groupinstall 'Development Tools' yum install tcl yum install libpcap libpcap-devel ...
- 基于zepto的移动端日期和时间选择控件
前段时间给大家分享过一个基于jQuery Mobile的移动端日期时间拾取器,大家反应其由于加载过大的插件导致影响调用速度.那么今天我把从网络上搜集到的两个适合移动端应用的日期和时间选择插件分享给大家 ...
- errcode 4103 invalid page hint 小程序模板消息推送遇到的坑
invalid page hint一直提示这个坑爹的就是,我的小程序没发布之前,也就是测试版本用这个格式是可以的 /pages/myGroup/myGroup?groupid=22***但是发布成功以 ...
- 鸟哥的linux私房菜学习-(五)Linux系统的在线求助man page与info page
1.man page man是manual(操作说明)的简写啦!只要下达:『man date』 马上就会有清楚的说明出现在你面前喔!如下所示: 进入man命令的功能后,你可以按下『空格键』往下翻页,可 ...
- 树链剖分( 洛谷P3384 )
我们有时候遇到这样一类题目,让我们维护树上路径的某些信息,这个时候发现我们无法用线段树或者树状数组来维护这些信息,那么我们就有着一种新的数据结构,树剖:将一棵树划分成若干条链,用数据结构去维护每条链, ...
- Android Studio移动鼠标显示悬浮提示的设置方法
欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...
- leetcode — copy-list-with-random-pointer
import java.util.*; /** * * Source : https://oj.leetcode.com/problems/copy-list-with-random-pointer/ ...
- Pycharm选择pyenv安装的Python版本
在macOS上使用pyenv实现Python多版本共存后,pyenv安装的Python版本存在于macOS下的 ~/.pyenv/versions/下. 在Pycharm时,选择此目录下对应的版本即可 ...
- Netty对Protocol Buffer多协议的支持(八)
Netty对Protocol Buffer多协议的支持(八) 一.背景 在上篇博文中笔者已经用代码演示了如何在netty中使用Protocol Buffer,然而细心的用户可能会发现一个明显的不足之处 ...