Android超时机制的处理(很不错)

    xiaoxiao2021-12-14  16

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

    超时机制主要有:

    1、HTTP请求超时机制

    2、Socket通信超时机制

    HTTP请求超时机制

    [java] view plain copy print ? 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();  }    }   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还行,用在项目中还是不够完善。自己写了一个例子,有不完善之处,欢迎大家指正。

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

    如何控制超时机制

    如何处理异常

    如何处理请求错误的

    [java] view plain copy print ? 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;          }        }   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关键字   不管是请求成功,还是失败,都需要关闭链接。  转载自 Liudroid的博客

    转载请注明原文地址: https://ju.6miu.com/read-964430.html

    最新回复(0)