閱讀214 返回首頁    go 阿裏雲 go 技術社區[雲棲]


對於Android的http請求的異常管理

https://www.open-open.com/lib/view/open1327556868217.html


在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("https://")) {
                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關鍵字 
不管是請求成功,還是失敗,都需要關閉鏈接。

最後更新:2017-04-02 17:51:23

  上一篇:go JavaScript數組的reverse和sort方法
  下一篇:go 百度2012暑期實習麵經(自動化平台研發)