zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Linux下高并发socket最大连接数所受的各种限制
    Oracle DB 使用资源管理
    Oracle DB 资源管理
    C++ 封装私有堆(Private Heap)
    用宏实现 C++ Singleton 模式
    基于 crt debug 实现的 Windows 程序内存泄漏检测工具
    如何养成良好的 C++ 编程习惯 —— 内存管理
    OCP-1Z0-053-V12.02-643题
    Oracle DB 通过SQL 优化管理性能
    OCP-1Z0-052-V8.02-141题
  • 原文地址:https://www.cnblogs.com/wayne173/p/4564036.html
Copyright © 2011-2022 走看看