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/ ...
随机推荐
- avro 1.8.2 (js)
5月15日发布的avro 1.8.2 已经包含了js版代码. 清华大学镜像地址: https://mirrors.tuna.tsinghua.edu.cn/apache/avro/avro-1.8.2 ...
- Linux - Shell常用指令
一.文件.目录操作命令 1.ls命令:显示文件和目录的信息 ls 以默认方式显示当前目录文件列表 ls -a 显示所有文件包括隐藏文件 ls -l 显示文件属性,包括大小,日期,符号连接,是否可读写及 ...
- 《MYSQL》----字符串的复杂函数,检索的七-天-排-重
接到了一个新的需求,拿到需求的时候瞬间有点头大,因为实在是有些棘手. 我们这个系统本身是个接口系统,总接口数大概在200个左右.外部会有很多用户在 不同的时间拿着不同参数去调我们的这些接口,用户的调集 ...
- RSA加解密实现
RSA是由MIT的三位数学家R.L.Rivest,A.Shamir和L.Adleman[Rivest等1978, 1979]提出的一种用数论构造双钥的方法,被称为MIT体制,后来被广泛称之为RSA体制 ...
- Ajax 的用法
1.什么是 Ajax? Ajax,英文名 Asynchronous JavaScript and XML,也就是异步的 JavaScript 和 XML.它不是一门新的语言,而是一种使用现有标准的新方 ...
- JavaScript的DOM编程--12--innerHTML属性
innerHTML属性: 1). 浏览器几乎都支持该属性, 但不是 DOM 标准的组成部分. innerHTML 属性可以用来读, 写某给定元素里的 HTML 内容 <html> < ...
- CRM项目总结
CRM项目总结 一:开发背景 在公司日益扩大的过程中,不可避免的会伴随着更多问题出现. 对外 : 如何更好的管理客户与公司的关系?如何更及时的了解客户日益发展的需求变 ...
- Python环境安装及编辑器配置(一)
在2018年决定写一些关于Python的文章,其实写博客这件事在2016年就有了,但是因为个人的一些原因一直被耽搁.所以2018年的目标之一就是写多一点的博客,不管是是生活还是工作.好吧,废话不多说, ...
- 通过 python的 __call__ 函数与元类 实现单例模式
简单一句话,当一个类实现__call__方法时,这个类的实例就会变成可调用对象. 直接上测试代码 class ClassA: def __call__(self, *args, **kwargs): ...
- 使用alembic进行数据库版本管理
前言 随着项目业务需求的不断变更,数据库的表结构修改难以避免,此时就需要对数据库的修改加以记录和控制,便于项目的版本管理和随意的升级和降级. Alembic就可以很好的解决这个问题.Alembic是S ...