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可以合并
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: J2SE中的序默认序列化
下一篇: SpringBoot框架搭建教程分享
推荐阅读
-
Android使用http协议与服务器通信的实例
-
长连接通信之服务器端与Android端使用ssl验证
-
Android 中自定义ContentProvider与ContentObserver的使用简单实例
-
python服务器与android客户端socket通信实例
-
AS3与PHP通信的五种方法(基于HTTP协议)_PHP教程
-
Android编程使用HTTP协议与TCP协议实现上传文件的方法
-
Android 中自定义ContentProvider与ContentObserver的使用简单实例
-
Android编程使用HTTP协议与TCP协议实现上传文件的方法
-
基于WebClient实现Http协议的Post与Get对网站进行模拟登陆和浏览实例
-
Android编程之客户端通过socket与服务器通信的方法