android网络编程及网络超时处理
来源:互联网 发布:iphone文档传mac 编辑:程序博客网 时间:2024/04/30 04:36
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。
0 0
- android网络编程及网络超时处理
- Android网络超时处理
- Android 网络请求超时处理方案
- android 网络访问超时
- android 网络超时
- Android 网络超时
- Java非阻塞NIO网络编程连接超时的处理
- Android - 网络编程 - JSON - 处理
- 网络连接 以及超时处理
- 网络编程中的超时检测
- 网络编程中的超时检测
- 网络编程中的超时检测
- 网络编程中的超时检测
- select_socket 网络超时编程实例
- 网络编程中的超时检测
- 网络编程中的超时检测
- 网络编程设置时间超时
- 网络编程中的超时检测
- spark sql 中 hive变量的使用记录
- bzoj 2142 礼物 (组合数学+数论)
- iOS开发 - 友盟分享(自定义分享)如何让新浪分享显示蓝色文字,其他平台内容不显示链接
- cad图层dwg,dxf转shp
- 我的WCF数据服务(四)涅槃
- android网络编程及网络超时处理
- Linux下C++程序中的内存泄露检查(valgrind)
- 汉字验证码
- 165.[LeetCode] Compare Version
- hibernate自动建表的方法
- 排序-选择排序
- 使用bBank.js解决IE下select标签innerHTML插入option的BUG
- 谈谈我对Ext的认识,元芳,你怎么看
- socket中的长连接和短连接浅析