android网络编程及网络超时处理

本文是收录的两篇关于这方面的文章

Android超时机制的处理

由于手机端应用的响应,与当时的无线通信网络状况有很大的关联。而通信网络往往具有不稳定,延迟长的特点。所以,在我们的应用程序中,当我们请求网络的时候,超时机制的应用就显得特别重要。

超时机制主要有:

1、HTTP请求超时机制
2、Socket通信超时机制

HTTP请求超时机制


public static void main(String[] args){  long a=System.currentTimeMillis();
try{
URL myurl = new URL(“http://www.baidu.cn”);
URLConnection myurlcon = myurl.openConnection();
myurlcon.setConnectTimeout(1000);
myurlcon.setReadTimeout(1000);
BufferedReader in = new BufferedReader(new InputStreamReader(myurlcon.getInputStream(),”UTF-8″));
String inputLine;  while ((inputLine = in.readLine()) != null){
System.out.println(inputLine);
in.close();
System.out.println(System.currentTimeMillis()-a);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}  }  

如果超时 将 抛出 以下 异常

java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
at java.io.BufferedInputStream.read(BufferedInputStream.java:313)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:606)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:554)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:940)
at com.Test.main(Test.java:52)

这里还有一篇文章讲的也比较好:

在android项目中,如果有用到http请求,就必须也应该加上http请求的超时管理,异常管理,项目中遇到这个需求,google上搜索到了一 大堆,但是写的都比较简单,做个demo还行,用在项目中还是不够完善。自己写了一个例子,有不完善之处,欢迎大家指正。

需要注意的地方:有三个方面

如何控制超时机制

如何处理异常

如何处理请求错误的


private class XmlAsyncLoader extends XmlResourceRequest {  private boolean mIsCancle = false;  private HttpGet mGet;  private HttpClient mHttp;  public XmlAsyncLoader(MxActivity<?> activity, String url)  throws MalformedURLException {  super(activity, url);  }  @Override  protected void doTaskInBackground() {  // 请求数据  if (mUrl.toLowerCase().startsWith("http://")) {  mGet  = initHttpGet(mUrl);  mHttp = initHttp();  try {  HttpResponse response = mHttp.execute(mGet);  if (mIsCancle) {  return;  }  if (response != null) {  if(response.getStatusLine().getStatusCode()!=HttpStatus.SC_OK){  onResponseError("network error");  Log.v(TAG, "the code is :"+response.getStatusLine().getStatusCode());  return;  }  notifyUpdateProgress(70);  Document doc = getDocumet(response);  Element root = doc.getDocumentElement();  NodeList appList = root  .getElementsByTagName(Item_ELEMENT_NAME);  final int len = appList.getLength();  if (len <= 0) {// 没有items  onFoundNoItems();  return;  }  for (int i = 0; i < len; i++) {  Element item = (Element) appList.item(i);  if (item.getNodeType() == Node.ELEMENT_NODE) {  HahaItemInfo info = createHahaItemIno(item);  if (mIsCancle){  return;  }  onFoundItem(info, 80 + 20 * (i + 1) / len);  addUrlToQueue(info.userIconUrl);  }  };  }  }catch(ConnectTimeoutException e){  onResponseError("time out");  } catch (ClientProtocolException e) {  --mCurrentPage;  e.printStackTrace();  } catch (IOException e) {  --mCurrentPage;  e.printStackTrace();  } catch (XmlPullParserException e) {  --mCurrentPage;  e.printStackTrace();  }finally{  notifyLoadFinish();  notifyLoadImages();  mHttp.getConnectionManager().shutdown();  }  }  }  private HttpClient initHttp() {  HttpClient client  = new DefaultHttpClient();  client.getParams().setIntParameter(  HttpConnectionParams.SO_TIMEOUT, TIME_OUT_DELAY); // 超时设置  client.getParams().setIntParameter(  HttpConnectionParams.CONNECTION_TIMEOUT, TIME_OUT_DELAY);// 连接超时  return client;  }  private HttpGet initHttpGet(String mUrl) {  HttpGet get = new HttpGet(mUrl);  initHeader(get);  return get;  }  @Override  public boolean tryCancel() {  Log.i(TAG, "tryCanle is working");  mGet.abort();  mIsCancle = true;  mHttp.getConnectionManager().shutdown();  notifyLoadFinish();  return true;  }  }  

这是一个异步任务类,发送get请求请求数据,解析服务器的响应数据,同时通知ui线程更新ui

在android中,互联网交互的写法有很多,可以使用apache提供的包,也可以使用google提供的api,我不知道那种更好,只是习惯于使用
apache的api。
1. 设置超时机制

 client.getParams().setIntParameter(HttpConnectionParams.SO_TIMEOUT, TIME_OUT_DELAY); // 超时设置client.getParams().setIntParameter(HttpConnectionParams.CONNECTION_TIMEOUT, TIME_OUT_DELAY);// 连接超时

这里设置了两种超时,第一种是请求超时,第二种时连接超时。

当向服务器发出请求后,请求和服务器建立socket连接,但是很长时间内都没有建立socket连接,这就时第一种请求超时,这种情况主要发生在请求了
一个不存在的服务器。超时之后,会抛出InterruptedIOException异常。
Timeout for blocking operations. The argument value is specified in
 milliseconds. An  InterruptedIOException is thrown if this timeout
 expires.
客户端已经与服务器建立了socket连接,但是服务器并没有处理客户端的请求,没有相应服务器,这就是第二种连接超时。这中超时会抛出
ConnectTimeoutException异常,ConnectTimeoutException继承自InterruptedIOException,所以只要捕获ConnectTimeoutException
就可以了。
2. 分析一下请求的过程
 2.1 HttpResponse response = mHttp.execute(mGet);
执行请求方法,获取服务器响应,(这里有个不太成熟的看法,response不可能为null,还有待验证)。
  2.2 获取请求响应码

if(response.getStatusLine().getStatusCode()!=HttpStatus.SC_OK){
                            onResponseError("network error");
                            Log.v(TAG, "the code is :"+response.getStatusLine().getStatusCode());
                            return;
                        }

  即使连接上服务器,并且从服务器上获取了数据,也有可能时服务器返回的错误信息,因此也需要特殊处理。
2.3 异常处理
  对于异常,不能简单的捕获就完事,例如上面的代码中,我请求第三页的数据,如果发生异常,请求不成功,那么我就需要让当前页数回滚,
如果成功了就不用回滚了,所以需要对异常进行处理
2.4 finally关键字
  不管是请求成功,还是失败,都需要关闭链接。

===============

android网络编程注意事项之一:移动网络下,防止网络超时甚至连接不上,解决办法--为网络请求设置代理

Android应用程序访问互联网资源时,在Wifi的情况下处理网络连接按照上文所讲述的方法步骤即可顺利实现;但如果当前Android设备的联网方式是通过移动运营商的网络服务为中转,间接访问的互联网资源时,则就涉及到在创建HTTP链接之前需要设置Proxy,即可尽量避免网络中断访问的情况,顺利访问互联网。

Proxy中文即代理。已经插入手机卡的Android设备,点击"设置"→"无线和网络"→"移动网络设置"→"接入点名称",任意点击一接入点,此时显示的内容即为当前运营商为使Android设备通过运营商网络顺利接入互联网而需要设置的代理信息。

通常,中国移动的接入点为CMWAP,代理IP是10.0.0.172,端口为80。

由于不同运营商其代理设置的不同,为保证代码的一致性及有效性,开发过程中需要封装出能够自适应各种不同Proxy环境并且能够顺利访问互联网的联网代码。

封装后的方法为openUrl(),代码如下:

public static HttpURLConnection openUrl(Context context, String urlStr) {  URL urlURL = null;  HttpURLConnection httpConn = null;  try {  urlURL = new URL(urlStr);  // 需要android.permission.ACCESS_NETWORK_STATE  // 在没有网络的情况下,返回值为null。  NetworkInfo networkInfo = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE))  .getActiveNetworkInfo();  // 如果是使用的运营商网络  if (networkInfo != null) {  if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {  // 获取默认代理主机ip  String host = android.net.Proxy.getDefaultHost();  // 获取端口  int port = android.net.Proxy.getDefaultPort();  if (host != null && port != -1) {  // 封装代理連接主机IP与端口号。  InetSocketAddress inetAddress = new InetSocketAddress(host, port);  // 根据URL链接获取代理类型,本链接适用于TYPE.HTTP  java.net.Proxy.Type proxyType = java.net.Proxy.Type.valueOf(urlURL.getProtocol().toUpperCase());  java.net.Proxy javaProxy = new java.net.Proxy(proxyType, inetAddress);  httpConn = (HttpURLConnection) urlURL.openConnection(javaProxy);  } else {  httpConn = (HttpURLConnection) urlURL.openConnection();  }  } else {  httpConn = (HttpURLConnection) urlURL.openConnection();  }  httpConn.setConnectTimeout(Const.NETWORK_OPEN_TIMEOUT);  httpConn.setReadTimeout(Const.NETWORK_READ_TIMEOUT);  httpConn.setDoInput(true);  } else {  // LogOut.out(this, "No Avaiable Network");  }  } catch (NullPointerException npe) {  npe.printStackTrace();  } catch (MalformedURLException e) {  e.printStackTrace();  } catch (IOException e) {  e.printStackTrace();  }  return httpConn;
}  

由于需要设置Proxy的情况为使用运营商网络,所以代码一开始即使用通过Context获得ConnectivityManager,执行ConnectivityManager.getActiveNetworkInfo()获取当前可用的网络。在有可用网络的情况下,判断其类型,如果networkInfo.getType()返回值为ConnectivityManager.TYPE_MOBILE,则需要设置Proxy;在返回值为ConnectivityManager.TYPE_WIFI的情况下则跳过设置Proxy的步骤。

对HttpURLConnection设置Proxy需要指定代理IP及端口号,android.net.Proxy解决了这个问题。执行Proxy.getDefaultHost()和Proxy.getDefaultPort()将返回代理主机的IP及开放端口号,并以这两个信息传参构造InetSocketAddress。InetSocketAddress为IP套接地址,其主要形式可由IP地址与端口号组合而成,亦可用主机域名加端口号组合而成,这种情况下将尝试将主机域名解析为IP地址。

封装的方法openUrl()两个参数中第二个参数为网络链接地址,将该地址构造出URL实例后,使用URL.getProtocol()方法即可知该链接地址所使用的协议类型。使用得到的链接协议类型,执行java.net.Proxy.Type的valueOf()方法进一步得到所需Proxy.Type。

在InetSocketAddress及Proxy.Type确定的情况下,即可构造java.net.Proxy实例,执行代码为new java.net.Proxy(proxyType, inetAddress)。将新生成的Proxy对象做为参数,执行URL.openConnection(javaProxy),即可得到使用Proxy设置连接互联网的HttpURLConnection。

android网络编程及网络超时处理相关推荐

  1. 迈入JavaWeb第一步,Java网络编程基础,TCP网络编程URL网络编程等

    文章目录 网络编程概述 网络通信要素 要素一IP和端口号 要素二网络协议 TCP网络编程 UDP网络编程 URL网络编程 Java网络编程基础 网络编程概述 Java是Internet上的语言,它从语 ...

  2. 如何连接Linux上的服务器 网络编程,Linux 网络编程 一

    一.网络编程基础 网络编程本身是一门很大的学问,涉及到的东西也很多,尤其是各种协议.先看图: 正如上图所示,网络编程中包含五大层面(也有区分六个层面),从应用层到物理层可以明显看出 越往下越接近计算机 ...

  3. 网络编程:网络协议简介

    这是张富涛的第10篇原创 网络编程:网络协议简介 网络协议在网络编程中是一个比较神秘的概念,今天就由我们揭开它神秘的面纱吧. 1. 什么是网络协议? 网络协议是指对于网络中传输的数据格式的规定.在计算 ...

  4. python 网络编程是什么_什么是网络编程-Python 网络编程-嗨客网

    Python网络编程网络编程教程 网络编程的本质是两个设备之间的数据交换,当然,在计算机网络中,设备主要指计算机.数据传递本身没有多大的难度,不就是把一个设备中的数据发送给两外一个设备,然后接受另外一 ...

  5. 13、python网络编程之网络通信协议

    python网络编程之网络通信协议 一.C/S与B/S架构 B/S架构 B/S架构中省去了客户端的开发,是基于浏览器(Browser)与服务端完成数据的通信 二.网络通信 什么是网络 网络是用物理链路 ...

  6. 【技术分享篇】从网卡到tcpip协议栈,再到应用程序丨tcp/ip网络编程丨网络api的实现原理丨sk_buff的作用

     从网卡 聊到tcp/ip协议栈,再到应用程序 1. posix tcp/ip网络编程 2. 网络api的实现原理 3. sk_buff的作用 [技术分享篇]面试中从网卡 聊到tcpip协议栈,再到应 ...

  7. 【网络编程】网络基础知识

    前言 小亭子正在努力的学习编程,接下来将开启javaEE的学习~~ 分享的文章都是学习的笔记和感悟,如有不妥之处希望大佬们批评指正~~ 同时如果本文对你有帮助的话,烦请点赞关注支持一波, 感激不尽~~ ...

  8. 网络编程中的超时检测

    http://blog.163.com/liukang_0404@126/blog/static/55682581201231955735693/ 我们在网络编程中常见的一种做法是:创建好套接字后以阻 ...

  9. python网络编程案例_Python 网络编程_python网络编程基础_python高级编程

    Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...

最新文章

  1. C#控制远程计算机的服务
  2. glob.glob 函数读取文件
  3. RDKit入门与进阶教程(30篇)
  4. 计算机网络 实验 使用端口完成地址转换,Wireshark抓包工具计算机网络实验解析...
  5. LeetCode 726. 原子的数量
  6. 「PKUSC2018」星际穿越 (70分做法)
  7. python lambda 判断_在Python的Filter中使用lambda函数时,为何达不到预期效果?
  8. HDOJ 5091 Beam Cannon 扫描线
  9. 上海海事大学c语言题库,上海海事大学,C语言试卷6
  10. 多方位全面解析:如何正确地写好一个iOS UI
  11. JavaScript学习手册五:JS数组
  12. go语言中如何使用select
  13. 菜鸟日记(yzy):集成Ucrop裁剪图片架构,并创建管理类使用
  14. python seo cms_「SEO帝国」 SEO中讲的 CMS是什么意思
  15. 关于java中的finalize()方法
  16. 【技术总结大全】【用来快速查询的文章】技术总结大全
  17. #创新应用#拓词:少壮不努力,老大用拓词!
  18. Flink使用lambda表达式报错:InvalidTypesException:could not be determined automatically, due to type erasure.
  19. [LINQ2Dapper]最完整Dapper To Linq框架(二)---动态化查询
  20. 如何卸载干净Fusion 360

热门文章

  1. VSCode配置C++环境(MSVC)
  2. 移动应用的AR滤镜和实时特效:提升用户创造力和娱乐体验
  3. 编程界“网络工程师”都用过的Python学习教程+PDF电子版曝光了
  4. XM外汇官网 xm-cnfx com 外汇新手如何才能把小金额的账户做大?
  5. Java入门基础知识点整理大放送,推荐保存
  6. angular 未登录状态拦截路由跳转
  7. IDA Pro切换到16bit模式,分析BootLoader
  8. Java初级开发工程师工作的岗位职责(合集)
  9. 强制缓存和协商缓存的区别
  10. 面向对象设计原则——开闭原则