android 使用HttpClient访问网络 服务器端与客户端交互问题

android 使用HttpClient访问网络 服务器端与客户端交互问题,第1张

解答:初步判断,json解析有问题。一般情况下,解析json必须要明确json字符串的内容。通俗地来讲,就是说你要知道整个json字符串的结构组成,有几个大括号{},包括嵌套的大括号{},有几个中括号[],包括嵌套的[]。然后由外及内,最外层肯定是大括号{},就是一个json对象,也就是JsonObject,接着再在这一层,看看有没有中括号[],有的话就是json数组,也就是JsonArray,当前层的字段值可以根据当前层的json对象和字段名获取。如此,往内再走下一层json对象,也就是说查看第二个大括号{},依此类推。

   这种功能实际上就是数据同步,同时要考虑手机本身、电量、网络流量等等限制因素,所以通常在移动端上有一下两个解决方案:

  1一种是定时去server查询数据,通常是使用HTTP协议来访问web服务器,称Polling(轮询);

  2还有一种是移动端和服务器建立长连接,使用XMPP长连接,称Push(推送)。

  从耗费的电量、流量和数据延迟性各方面来说,Push有明显的优势。但是使用Push的缺点是:

  对于客户端:实现和维护相对成本高,在移动无线网络下维护长连接,相对有一些技术上的开发难度。

  对于服务器:如何实现多核并发,cpu作业调度,数量庞大的长连接并发维护等技术,仍存在开发难点。

  在讲述Push方案的原理前,先了解一下移动无线网络的特点。

  移动无线网络的特点:

  因为 IP v4 的 IP 量有限,运营商分配给手机终端的 IP 是运营商内网的 IP,手机要连接 Internet,就需要通过运营商的网关做一个网络地址转换(Network Address Translation,NAT)。简单的说运营商的网关需要维护一个外网 IP、端口到内网 IP、端口的对应关系,以确保内网的手机可以跟 Internet 的服务器通讯

  GGSN(Gateway GPRS

Support Node 网关GPRS支持结点)模块就实现了NAT功能。

因为大部分移动无线网络运营商都是为了减少网关的NAT映射表的负荷,所以如果发现链路中有一段时间没有数据通讯时,会删除其对应表,造成链路中断。

Push在Android平台上长连接的实现:

既然自己知道自己移动端要和Internet进行通信,必须通过运营商的网关,所以,为了不让NAT映射表失效,咋们需要定时向Internet发送数据,因为只是为了不然NAT映射表失效,所以只需发送长度为0的数据即可。

这时候就要用到定时器,在android系统上,定时器通常有一下两种:

1javautilTimer

2androidappAlarmManager

分析:

Timer:可以按照计划或者时间周期来执行相关的任务。但是Timer需要用WakeLock来让CPU保持唤醒状态,才能保证任务的执行,这样子会消耗大量流量;当CPU处于休眠的时候,就不能唤醒执行任务,所以应用于移动端明显是不合适。

AlarmManager:AlarmManager类是属于android系统封装好来管理RTC模块的管理类。这里就涉及到RTC模块,要更好地了解两者的区别,就要明白两者真正的区别。

RTC(Real- Time Clock)实时闹钟在一个嵌入式系统中,通常采用RTC

来提供可靠的系统时间,包括时分秒和年月日等;而且要求在系统处于关机状态下它也能够正常工作(通常采用后备电池供电),它的外围也不需要太多的辅助电路,典型的就是只需要一个高精度的32768KHz

晶体和电阻电容等。(如果对这方面感兴趣,可以自己查阅相关资料,这里就说个大概)

好了,回来正题。所以,AlarmManager又称全局定时闹钟。这意味着,当自己用使用AlarmManager来定时执行任务,CPU可以正常地休眠,只有在执行任务是,才唤醒CPU,这个过程是很短时间的。

下面简单来说明其使用:

1类似于Timer功能:

//获得闹钟管理器

AlarmManager

am = (AlarmManager)getSystemService(ALARM_SERVICE);

//设置任务执行计划

amsetRepeating(AlarmManagerELAPSED_REALTIME, firstTime, 51000,

sender);//从firstTime才开始执行,每隔5秒再执行

2实现全局定时功能:

//获得闹钟管理器

AlarmManager

am = (AlarmManager)getSystemService(ALARM_SERVICE);

//设置任务执行计划

amsetRepeating(AlarmManagerELAPSED_REALTIME_WAKEUP, firstTime,

51000, sender);//从firstTime才开始执行,每隔5秒再执行

总结:在android客户端使用Push推送时,应该使用AlarmManager来实现心跳功能,使其真正实现长连接。

OkHttp是一个相对成熟的解决方案,据说Android44的源码中可以看到HttpURLConnection已经替换成OkHttp实现了。所以我们更有理由相信OkHttp的强大。

OkHttp 处理了很多网络疑难杂症:会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当第一个IP连接失败的时候,OkHttp会自动尝试下一个IP。OkHttp还处理了代理服务器问题和SSL握手失败问题。

使用 OkHttp 无需重写您程序中的网络代码。OkHttp实现了几乎和javanetHttpURLConnection一样的API。如果你用了 Apache HttpClient,则OkHttp也提供了一个对应的okhttp-apache 模块。

package comtest;

import javaioBufferedReader;

import javaioInputStreamReader;

import javaioOutputStream;

import javanetHttpURLConnection;

import javanetURL;

import javanetURLEncoder;

import javautilHashMap;

import javautilMap;

import orgjsonJSONObject;

import androidappActivity;

import androidcontentIntent;

import androidosBundle;

import androidosHandler;

import androidosLooper;

public class TestPost extends Activity{

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

superonCreate(savedInstanceState);

setContentView(Rlayoutloading);

new Handler()postDelayed(new Runnable() {

@Override

public void run() {

final Map<String, String> params0 = new HashMap<String, String>();

params0put("username", username);

params0put("password", password);

final String url0 = "http://192168011:80/xxxxphp";

Runnable downloadRun = new Runnable() {

@Override

public void run() {

Looperprepare();

try {

String result0 = sendPostRequest(

params0, url0);

JSONObject jsonObject = new JSONObject(result0);

String status = jsonObjectgetString("status");

String message = jsonObjectgetString("message");

if (statusequals("success")) {

//成功干啥

} else {

//失败干啥

}

} catch (Exception e) {

//出现异常干啥

}

}

};

new Thread(downloadRun)start();

}

}, 200);

}

//post请求方法

public String sendPostRequest(Map<String, String> params, String actionurl)

throws Exception {

String URl = actionurl;

StringBuilder sb = new StringBuilder();

if (params != null && !paramsisEmpty()) {

for (MapEntry<String, String> entry : paramsentrySet()) {

sbappend(entrygetKey())append('=')

append(URLEncoderencode(entrygetValue(), "UTF-8"))

append('&');

}

sbdeleteCharAt(sblength() - 1);

}

byte[] entitydata = sbtoString()getBytes();// 得到实体的二进制数据

URL url = new URL(URl);

HttpURLConnection conn = (HttpURLConnection) urlopenConnection();

connsetDoInput(true);

connsetRequestMethod("POST");

connsetConnectTimeout(10000);

connsetDoOutput(true);// 如果通过post提交数据,必须设置允许对外输出数据

connsetUseCaches(false);// 是否缓存

connsetRequestProperty("Content-Type","application/x-www-form-urlencoded");

connsetRequestProperty("Content-Length",StringvalueOf(entitydatalength));

OutputStream outStream = conngetOutputStream();

outStreamwrite(entitydata);

outStreamflush();

outStreamclose();

BufferedReader bufferRead = null;

if(conngetResponseCode() == 200){

bufferRead = new BufferedReader(new InputStreamReader(conngetInputStream()));

}

String result = "";

String readLine = null;

while ((readLine = bufferReadreadLine()) != null) {

result += readLine;

}

bufferReadclose();

conndisconnect();

return result;

}

}

我用的是这种方法

普通不会架tomcat服务器的话,就用myeclipse,安装好tomcat,然后再开启就可以进行调试了。android模拟器访问tomcat的程序,只要访问你本机的ip地址就行了。我当时使用10002不行,一定要使用本地ip地址才能访问到,可能是我当时设置不好吧。要是你的手机要访问本地服务器,则可能要把tomcat架到公网上去解析好,才能进行访问了。我调试程序都是用虚拟机做服务器,或者直接弄到自己的公网服务器去。

  虽然只有十分

  但是还是给你写一段 android中测试 跑得了 加点分可以继续追问我哦 呵呵~~~~

  public static String getHtml( String urlpath,String encoding) throws Exception {

  URL url = new URL(urlpath);

  //实例化一个HTTP连接对象conn

  HttpURLConnection conn = (HttpURLConnection)urlopenConnection();

  //定义请求方式为GET,其中GET的格式需要注意

  connsetRequestMethod("GET");

  //定义请求时间,在ANDROID中最好是不好超过10秒。否则将被系统回收。

  connsetConnectTimeout(61000);

  if(conngetResponseCode()== 200){

  InputStream inStream = conngetInputStream();

  byte[] data = readStream(inStream);

  return new String(data,encoding);

  }

  return null;

  }

  public static byte[] readStream(InputStream inStream) throws Exception{

  ByteArrayOutputStream outStream = new ByteArrayOutputStream();

  byte[] buffer = new byte[1024];

  int len= -1;

  //将输入流不断的读,并放到缓冲区中去。直到读完

  while((len=inStreamread(buffer))!=-1){

  //将缓冲区的数据不断的写到内存中去。

  outStreamwrite(buffer, 0, len);

  }

  outStreamclose();

  inStreamclose();

  return outStreamtoByteArray();

  }

解决方法很多!很简单啊,手机连上的网是广域网,你自己搞的tomcat是局域网上的东西,怎么能访问?

除非你把你的

http://ip:8080/myapp

这个地址弄成一个广域网上的域名才可以的。

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » android 使用HttpClient访问网络 服务器端与客户端交互问题

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情