Android 关于异步Http请求,以及编码问题

大家都知道可以使用一个继承了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;
}

 

posted @ 2015-06-09 17:10  達達尼亞  阅读(408)  评论(0编辑  收藏  举报