Android使用http协议与服务器通信的实例

网上介绍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可以合并

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-09-27 11:57:12

Android使用http协议与服务器通信的实例的相关文章

多线程-android菜鸟 关于客户端与服务器通信 求助

问题描述 android菜鸟 关于客户端与服务器通信 求助 我是个android开发菜鸟 切入正题 listview的图文混排 用json从服务器通过post请求方式获得数据 (BaseClient和handler多线程方式) 然后将数据解析 用baseadapter填到布局界面中 求助 解决方案 Android客户端和服务器通信android客户端与服务器通信问题android服务器和客户端通信1 解决方案二: 然后lz你想求助的是什么呢.这是一个工程还是要思路还是要参考资料

Android编程之客户端通过socket与服务器通信的方法

  Android编程之客户端通过socket与服务器通信的方法        本文实例讲述了Android编程之客户端通过socket与服务器通信的方法.分享给大家供大家参考,具体如下: 下面是一个demo,Android客户端通过socket与服务器通信. 由于Android里面可以完全使用java.io.*包和java.net.*包,那么,实际上,逻辑部分与J2SE没有区别.只是UI代码不一样. Android客户端通过socket与服务器通信分为下面5步: (1)通过IP地址和端口实例化

Android编程之客户端通过socket与服务器通信的方法_Android

本文实例讲述了Android编程之客户端通过socket与服务器通信的方法.分享给大家供大家参考,具体如下: 下面是一个demo,Android客户端通过socket与服务器通信. 由于Android里面可以完全使用java.io.*包和java.net.*包,那么,实际上,逻辑部分与J2SE没有区别.只是UI代码不一样. Android客户端通过socket与服务器通信分为下面5步: (1)通过IP地址和端口实例化Socket,请求连接服务器: 复制代码 代码如下: socket = new

Android HTTP 实现与服务器通信

  Android与服务器通信通常采用HTTP通信方式和Socket通信方式,而HTTP通信方式又分get和post两种方式.至于Socket通信会在以后的博文中介绍. HTTP协议简介: HTTP (Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种协议. HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接.从建立连接到关闭连接的过程称为"一次连接&q

c#如何通过onc/rpc协议与Linux下的服务器通信

问题描述 c#如何通过onc/rpc协议与Linux下的服务器通信有谁做过这方面的吗? 解决方案 解决方案二:可以先看看别人是怎么做的:http://sourceforge.net/projects/remoteteanet/

ios项目中客户端与服务器通信 认证加密怎么做?

问题描述 ios项目中客户端与服务器通信 认证加密怎么做? ios项目中客户端与服务器通信 认证加密怎么做? 主要是还不理解 解决方案 Apple 的 iAP认证,需要参考协议 + 加密 IC 来实现不懂就要看协议,是比较复杂,且只是 E 文版本的文档 解决方案二: iAP是内购吧,与问题不太相关吧..通信中感觉主要做好这几点吧1.HTTPS2.字符串参数.文件等敏感信息传输过程中保持加密状态,至于加密算法,建议使用非对称的RSA

Android通过HTTP协议实现上传文件数据_Android

本文实例为大家分享了Android通过HTTP协议实现上传文件数据的具体代码,供大家参考,具体内容如下 SocketHttpRequester.java package cn.itcast.utils; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.InputStream; import java.io.Inp

模拟器与pc通讯-android模拟器与pc的相互通信

问题描述 android模拟器与pc的相互通信 我现在再能实现模拟器联系pc,pc作为服务器被动的做出反应.不能实现pc发消息给模拟器.那要如何实现相互的通信呢 代码如下: package com.example.socket_android; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStreamWrit

C#winform网络应用小程序,客户端有多个窗体,每个窗体怎么与服务器通信?

问题描述 C#winform网络应用小程序,客户端有多个窗体,form1,form2,form3,.....form1已经与服务器连接了,可以正常通信,但是form2也要与服务器通信,难道再次与服务器建立一个连接? 解决方案 解决方案二:这个和有多少个窗体压根没关系,例如你使用的是TCP/IP协议的话,你可以将Socket弄成static的变量,然后所有Form都可以使用它了,不过用之前最好判断一下是否连接socket.Connected解决方案三:我觉得你可以在网上找找有关类似QQ的程序,很多