对于Android的http请求的异常管理

fmms 13年前
     在android项目中,如果有用到http请求,就必须也应该加上http请求的超时管理,异常管理,项目中遇到这个需求,google上搜索到了一大堆,但是写的都比较简单,做个demo还行,用在项目中还是不够完善。自己写了一个例子,有不完善之处,欢迎大家指正。    <br /> 需要注意的地方:有三个方面    <br /> 如何控制超时机制    <br /> 如何处理异常    <br /> 如何处理请求错误的    <br />    <pre class="brush:java; toolbar: true; auto-links: false;">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;         }     }</pre>    <br /> 这是一个异步任务类,发送get请求请求数据,解析服务器的响应数据,同时通知ui线程更新ui    <br /> 在android中,互联网交互的写法有很多,可以使用apache提供的包,也可以使用google提供的api,我不知道那种更好,只是习惯于使用    <br /> apache的api。    <br /> 1. 设置超时机制    <br />    <pre class="brush:java; toolbar: true; auto-links: false;"> client.getParams().setIntParameter(                     HttpConnectionParams.SO_TIMEOUT, TIME_OUT_DELAY); // 超时设置             client.getParams().setIntParameter(                     HttpConnectionParams.CONNECTION_TIMEOUT, TIME_OUT_DELAY);// 连接超时</pre>    <br /> 这里设置了两种超时,第一种是请求超时,第二种时连接超时。    <br /> 当向服务器发出请求后,请求和服务器建立socket连接,但是很长时间内都没有建立socket连接,这就时第一种请求超时,这种情况主要发生在请求了    <br /> 一个不存在的服务器。超时之后,会抛出InterruptedIOException异常。    <br /> Timeout for blocking operations. The argument value is specified in    <br />  milliseconds. An  InterruptedIOException is thrown if this timeout    <br />  expires.    <br /> 客户端已经与服务器建立了socket连接,但是服务器并没有处理客户端的请求,没有相应服务器,这就是第二种连接超时。这中超时会抛出    <br /> ConnectTimeoutException异常,ConnectTimeoutException继承自InterruptedIOException,所以只要捕获ConnectTimeoutException    <br /> 就可以了。    <br /> 2. 分析一下请求的过程    <br /> 2.1 HttpResponse response = mHttp.execute(mGet);    <br /> 执行请求方法,获取服务器响应,(这里有个不太成熟的看法,response不可能为null,还有待验证)。    <br />   2.2 获取请求响应码    <br />    <pre class="brush:java; toolbar: true; auto-links: false;"> if(response.getStatusLine().getStatusCode()!=HttpStatus.SC_OK){                             onResponseError("network error");                             Log.v(TAG, "the code is :"+response.getStatusLine().getStatusCode());                             return;                         }</pre>    <br /> 即使连接上服务器,并且从服务器上获取了数据,也有可能时服务器返回的错误信息,因此也需要特殊处理。    <br /> 2.3 异常处理    <br /> 对于异常,不能简单的捕获就完事,例如上面的代码中,我请求第三页的数据,如果发生异常,请求不成功,那么我就需要让当前页数回滚,    <br /> 如果成功了就不用回滚了,所以需要对异常进行处理    <br /> 2.4 finally关键字    <br /> 不管是请求成功,还是失败,都需要关闭链接。