標籤:
大家都知道可以使用一個繼承了AsyncTask的類去實現非同步作業,再有個Http請求的類就可以解決了,現在我說下裡面的細節問題,比如長時間無反應,編碼問題,以及一些HTML相關的處理。
首先說下長時間無反應的問題,AsyncTask有個get方法,
/** * Waits if necessary for at most the given time for the computation * to complete, and then retrieves its result. * * @param timeout Time to wait before cancelling the operation. * @param unit The time unit for the timeout. * * @return The computed result. * * @throws CancellationException If the computation was cancelled. * @throws ExecutionException If the computation threw an exception. * @throws InterruptedException If the current thread was interrupted * while waiting. * @throws TimeoutException If the wait timed out. */ public final Result get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return mFuture.get(timeout, unit); }
可以看到調用此方法會有異常情況,可以在異常情況的時候處理,其實這個分的很細了,有網路異常,執行異常,逾時異常,可以參考下面的代碼去實現,會調用AsyncTask的cancel(boolean flag) 方法取消操作。
ArticleTask task = new ArticleTask(); task.execute(ARTITLC_URL); //超過5s鐘沒有執行完成,取消此非同步作業 try { task.get(5000, TimeUnit.MILLISECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { // TODO Auto-generated catch block e.printStackTrace(); task.cancel(false); dialog.dismiss(); }
然後說下如果是請求的html響應,如何處理HTML標籤,這裡是簡單的處理,詳細的還要用別的方法,以後補充吧。下面的代碼基本能說明問題了。
//去除html標籤 Spanned spanned = Html.fromHtml(result); TextView textView = new TextView(MainActivity.this); textView.setText(spanned); textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); //是返回中的a標籤產生連結 textView.setMovementMethod(new LinkMovementMethod());
最後說下傳遞過程中的編碼問題,其實主要是針對中文的。如果有參數,參數要轉碼,返回的內容也要轉碼,所以要涉及到兩個地方,下面的代碼注釋應該可以說清楚了。最開始沒注意,結果亂碼,後來使用 result=new String(result.getBytes("ISO-8859-1"),"utf-8"); 也解決了,不過看下面的方法更方便。
// 封裝表單 if (null != params && !params.isEmpty()) { List<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>(); for (Map.Entry<String, Object> entry : params.entrySet()) { String name = entry.getKey(); String value = entry.getValue().toString(); BasicNameValuePair pair = new BasicNameValuePair(name, value); parameters.add(pair); } try { //此處為了避免中文亂碼,保險起見要加上編碼格式 UrlEncodedFormEntity encodedFormEntity = new UrlEncodedFormEntity( parameters, encoding); post.setEntity(encodedFormEntity); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); Log.d("shang", "UnsupportedEncodingException"); } } try { HttpResponse response = client.execute(post); if(HTTP_STATUS_OK == response.getStatusLine().getStatusCode()) { //擷取伺服器請求的返回結果,注意此處為了保險要加上編碼格式 result = EntityUtils.toString(response.getEntity(), encoding); } else { throw new Exception("Invalide response from API" + response.toString()); } } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
下面還有個別人的解決辦法,不過沒解決我當時的問題,也列出來吧,有些地方還是可以借鑒的。
public Map<String, Object> CreateNote(int albumId, String title, String remark) { String noteId = ""; Map<String, Object> map = new HashMap<String, Object>(); try { HttpParams parms = new BasicHttpParams(); parms.setParameter("charset", HTTP.UTF_8); HttpConnectionParams.setConnectionTimeout(parms, 8 * 1000); HttpConnectionParams.setSoTimeout(parms, 8 * 1000); HttpClient httpclient = new DefaultHttpClient(parms); HttpPost httppost = new HttpPost(ConfigHelper.CreateUri); httppost.addHeader("Authorization", mToken); httppost.addHeader("Content-Type", "application/json"); httppost.addHeader("charset", HTTP.UTF_8); JSONObject obj = new JSONObject(); obj.put("title", title); obj.put("categoryId", mCategoryId); obj.put("sourceUrl", GetSourceUri()); JSONArray arr = new JSONArray(); arr.put(DateFormat.format("yyyyMM",Calendar.getInstance(Locale.CHINA))); obj.put("tags", arr); obj.put("content", remark); httppost.setEntity(new StringEntity(obj.toString(), HTTP.UTF_8)); HttpResponse response; response = httpclient.execute(httppost); int code = response.getStatusLine().getStatusCode(); if (code == ConstanDefine.ErrorCode.SuccOfHttpStatusCode) { String rev = EntityUtils.toString(response.getEntity()); obj = new JSONObject(rev); noteId = obj.getString("id"); map.put("return_code", "0"); map.put("content", rev); } } catch (Exception e) { if (map.containsKey("return_code")) { map.remove("return_code"); } map.put("return_code", "1"); } return map;}
Android 關於非同步Http請求,以及編碼問題