网上介绍Android上http通信的文章很多,不过大部分只给出了实现代码的片段,一些注意事项和如何设计一个合理的类用来处理所有的http请求以及返回结果,一般都不会提及。因此,自己对此做了些总结,给出了我的一个解决方案。

首先,需要明确一下http通信流程,Android目前提供两种http通信方式,HttpURLConnection和HttpClient,HttpURLConnection多用于发送或接收流式数据,因此比较适合上传/下载文件,HttpClient相对来讲更大更全能,但是速度相对也要慢一点。在此只介绍HttpClient的通信流程:
1.创建HttpClient对象,改对象可以用来多次发送不同的http请求
2.创建HttpPost或HttpGet对象,设置参数,每发送一次http请求,都需要这样一个对象
3.利用HttpClient的execute方法发送请求并等待结果,该方法会一直阻塞当前线程,直到返回结果或抛出异常。
4.针对结果和异常做相应处理
根据上述流程,发现在设计类的时候,有几点需要考虑到:
1.HttpClient对象可以重复使用,因此可以作为类的静态变量
2.HttpPost/HttpGet对象一般无法重复使用(如果你每次请求的参数都差不多,也可以重复使用),因此可以创建一个方法用来初始化,同时设置一些需要上传到服务器的资源
3.目前Android不再支持在UI线程中发起Http请求,实际上也不该这么做,因为这样会阻塞UI线程。因此还需要一个子线程,用来发起Http请求,即执行execute方法
4.不同的请求对应不同的返回结果,对于如何处理返回结果(一般来说都是解析json&更新UI),需要有一定的自由度。
5.最简单的方法是,每次需要发送http请求时,开一个子线程用于发送请求,子线程中接收到结果或抛出异常时,根据情况给UI线程发送message,最后在UI线程的handler的handleMessage方法中做结果解析和UI更新。这么写虽然简单,但是UI线程和Http请求的耦合度很高,而且代码比较散乱、丑陋。
基于上述几点原因,我设计了一个PostRequest类,用于满足我的http通信需求。我只用到了Post请求,如果你需要Get请求,也可以改写成GetRequest
package com.handspeaker.network;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.os.Handler;
import android.util.Log;
/**
*
* 用于封装&简化http通信
*
*/
public class PostRequest implements Runnable {
private static final int NO_SERVER_ERROR=1000;
//服务器地址
public static final String URL = "fill your own url";
//一些请求类型
public final static String ADD = "/add";
public final static String UPDATE = "/update";
public final static String PING = "/ping";
//一些参数
private static int connectionTimeout = 60000;
private static int socketTimeout = 60000;
//类静态变量
private static HttpClient httpClient=new DefaultHttpClient();
private static ExecutorService executorService=Executors.newCachedThreadPool();
private static Handler handler = new Handler();
//变量
private String strResult;
private HttpPost httpPost;
private HttpResponse httpResponse;
private OnReceiveDataListener onReceiveDataListener;
private int statusCode;
/**
* 构造函数,初始化一些可以重复使用的变量
*/
public PostRequest() {
strResult = null;
httpResponse = null;
httpPost = new HttpPost();
}
/**
* 注册接收数据监听器
* @param listener
*/
public void setOnReceiveDataListener(OnReceiveDataListener listener) {
onReceiveDataListener = listener;
}
/**
* 根据不同的请求类型来初始化httppost
*
* @param requestType
* 请求类型
* @param nameValuePairs
* 需要传递的参数
*/
public void iniRequest(String requestType, JSONObject jsonObject) {
httpPost.addHeader("Content-Type", "text/json");
httpPost.addHeader("charset", "UTF-8");
httpPost.addHeader("Cache-Control", "no-cache");
HttpParams httpParameters = httpPost.getParams();
HttpConnectionParams.setConnectionTimeout(httpParameters,
connectionTimeout);
HttpConnectionParams.setSoTimeout(httpParameters, socketTimeout);
httpPost.setParams(httpParameters);
try {
httpPost.setURI(new URI(URL + requestType));
httpPost.setEntity(new StringEntity(jsonObject.toString(),
HTTP.UTF_8));
} catch (URISyntaxException e1) {
e1.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* 新开一个线程发送http请求
*/
public void execute() {
executorService.execute(this);
}
/**
* 检测网络状况
*
* @return true is available else false
*/
public static boolean checkNetState(Activity activity) {
ConnectivityManager connManager = (ConnectivityManager) activity
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connManager.getActiveNetworkInfo() != null) {
return connManager.getActiveNetworkInfo().isAvailable();
}
return false;
}
/**
* 发送http请求的具体执行代码
*/
@Override
public void run() {
httpResponse = null;
try {
httpResponse = httpClient.execute(httpPost);
strResult = EntityUtils.toString(httpResponse.getEntity());
} catch (ClientProtocolException e1) {
strResult = null;
e1.printStackTrace();
} catch (IOException e1) {
strResult = null;
e1.printStackTrace();
} finally {
if (httpResponse != null) {
statusCode = httpResponse.getStatusLine().getStatusCode();
}
else
{
statusCode=NO_SERVER_ERROR;
}
if(onReceiveDataListener!=null)
{
//将注册的监听器的onReceiveData方法加入到消息队列中去执行
handler.post(new Runnable() {
@Override
public void run() {
onReceiveDataListener.onReceiveData(strResult, statusCode);
}
});
}
}
}
/**
* 用于接收并处理http请求结果的监听器
*
*/
public interface OnReceiveDataListener {
/**
* the callback function for receiving the result data
* from post request, and further processing will be done here
* @param strResult the result in string style.
* @param StatusCode the status of the post
*/
public abstract void onReceiveData(String strResult,int StatusCode);
}
}
代码使用了观察者模式,任何需要接收http请求结果的类,都要实现OnReceiveDataListener接口的抽象方法,同时PostRequest实例调用setOnReceiveDataListener方法,注册该监听器。完整调用步骤如下:
1.创建PostRequest对象,实现onReceiveData接口,编写自己的onReceiveData方法
2.注册监听器
3.调用PostRequest的iniRequest方法,初始化本次request
4.调用PostRequest的execute方法
可能的改进:
1.如果需要多个观察者,可以把只能注册单个监听器改为可以注册多个监听器,维护一个监听器List。
2.如果需求比较简单,并希望调用流程更简洁,iniRequest和execute可以合并
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# android和服务器通信
# android
# https通信
# android与服务器通信
# Android使用WebSocket实现多人游戏
# SpringBoot webSocket实现发送广播、点对点消息和Android接收
# Android中使用WebSocket实现群聊和消息推送功能(不使用WebView)
# android基于socket的局域网内服务器与客户端加密通信
# Android实现蓝牙客户端与服务器端通信示例
# Android编程之客户端通过socket与服务器通信的方法
# python服务器与android客户端socket通信实例
# android利用websocket协议与服务器通信
# 重复使用
# 如果你
# 出了
# 多个
# 几点
# 抛出
# 自己的
# 都是
# 都要
# 在此
# 也要
# 两种
# 更大
# 有一定
# 很高
# 这样一个
# 考虑到
# 还需要
# 新开
# 上也
相关文章:
定制建站是什么?如何实现个性化需求?
独立制作一个网站多少钱,建立网站需要花多少钱?
制作表格网站有哪些,线上表格怎么弄?
视频网站app制作软件,有什么好的视频聊天网站或者软件?
香港服务器建站指南:免备案优势与SEO优化技巧全解析
免费制作海报的网站,哪位做平面的朋友告诉我用什么软件做海报比较好?ps还是cd还是ai这几个软件我都会些我是做网页的?
整人网站在线制作软件,整蛊网站退不出去必须要打我是白痴才能出去?
制作旅游网站html,怎样注册旅游网站?
湖北网站制作公司有哪些,湖北清能集团官网?
如何快速搭建响应式可视化网站?
网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?
山东网站制作公司有哪些,山东大源集团官网?
家庭建站与云服务器建站,如何选择更优?
教育培训网站制作流程,请问edu教育网站的域名怎么申请?
怎么将XML数据可视化 D3.js加载XML
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
网站制作公司广州有几家,广州尚艺美发学校网站是多少?
如何设置并定期更换建站之星安全管理员密码?
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
如何配置支付宝与微信支付功能?
营销式网站制作方案,销售哪个网站招聘效果最好?
建站之星体验版:智能建站系统+响应式设计,多端适配快速建站
建站之星伪静态规则如何正确配置?
如何在云指建站中生成FTP站点?
如何做网站制作流程,*游戏网站怎么搭建?
韩国服务器如何优化跨境访问实现高效连接?
如何在万网ECS上快速搭建专属网站?
电商平台网站制作流程,电商网站如何制作?
小说建站VPS选用指南:性能对比、配置优化与建站方案解析
网站制作网站,深圳做网站哪家比较好?
建站之星如何实现PC+手机+微信网站五合一建站?
制作宣传网站的软件,小红书可以宣传网站吗?
小型网站建站如何选择虚拟主机?
孙琪峥织梦建站教程如何优化数据库安全?
山东云建站价格为何差异显著?
婚礼视频制作网站,学习*后期制作的网站有哪些?
如何在腾讯云服务器快速搭建个人网站?
如何在Golang中引入测试模块_Golang测试包导入与使用实践
建站主机功能解析:服务器选择与快速搭建指南
建站VPS能否同时实现高效与安全翻墙?
代刷网站制作软件,别人代刷火车票靠谱吗?
微课制作网站有哪些,微课网怎么进?
宁波自助建站系统如何快速打造专业企业网站?
股票网站制作软件,网上股票怎么开户?
在线制作视频的网站有哪些,电脑如何制作视频短片?
网站企业制作流程,用什么语言做企业网站比较好?
如何在云主机快速搭建网站站点?
h5在线制作网站电脑版下载,h5网页制作软件?
宝塔建站助手安装配置与建站模板使用全流程解析
*请认真填写需求信息,我们会在24小时内与您取得联系。