編輯:Android開發實例
在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. AnInterruptedIOException
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自身和保持在對於時間裡可改善。這些最佳實踐包括交互設計功能,性能,安全性和私隱,兼容性,測試,分
EditText和TextView一樣,也可以進行圖文混排。所不同的是,TextView只用於顯示圖文混排效果,而EditText不僅可顯示,也可混合輸入文字和圖
前言 SQLite是一種輕量級的小型數據庫,雖然比較小,但是功能相對比較完善,一些常見的數據庫基本功能也具有,在現在的嵌入式系統中使用該數據庫的比較多,因為
什麼是AppWidget?AppWidget就是我們平常在桌面上見到的那種一個個的小窗口,利用這個小窗口可以給用戶提供一些方便快捷的操作。本篇打算從以下幾個點來介