最近做项目要求使用到网络,想来想去选择了AsyncHttpClient框架开进行APP开发。在这里把我工作期间遇到的问题以及对AsyncHttpClient的使用经验做出相应总结,希望能对您的学习有所帮助。

  首先按照惯例先来简单了解一些AsyncHttpClient网络框架的一些知识。

1、简介

  Android中网络请求一般使用Apache HTTP Client或者采用HttpURLConnect,但是直接使用这两个类库需要写大量的代码才能完成网络post和get请求,而使用android-async-http这个库可以大大的简化操作,它是基于Apache’s HttpClient ,所有的请求都是独立在UI主线程之外,通过回调方法处理请求结果,采用android  Handler message 机制传递信息。

2、特性

(1)采用异步http请求,并通过匿名内部类处理回掉结果

(2)http请求独立在UI主线程之外

(3)采用线程池来处理并发请求

(4)采用RequestParams类创建GET/POST参数

(5)不需要第三方包即可支持Multipart file文件上传

(6)大小只有25kb

(7)自动为各种移动电话处理连接断开时请求重连

(8)超快的自动gzip响应解码支持

(9)使用BinaryHttpResponseHandler类下载二进制文件(如图片)

(10)使用JsonHttpResponseHandler类可以自动将响应结果解析为json格式(下面会重点讲解JsonHttpResponseHandler在使用过程中存在的问题)

(11)持久化cookie存储,可以将cookie保存到你的应用程序的SharedPreferences中

以上的理论源于网友的博客,有兴趣的朋友如果想了解更多的关于AsyncHttpClient的理论知识可以去参考一下这位网友的博客

《Android网络请求框架AsyncHttpClient详解》:http://blog.csdn.net/xiaohui2015/article/details/51462782

3、使用办法

  在讲解实例之前,请先看接口文档,结合接口文档和实例学习起来更清晰。

用户登录接口文档:

接口地址:http://xxx.xxx.xxx/MobileService/userLogin

备注:

请求参数:

{

  username:”用户登录”,

  password:”密码”

}

返回结果:

{

  “code”:”状态码”,1000 返回成功 其他失败

  “message”:”提示信息”,

  “data”:{

      userid:”用户id”,

      supplier:”供应商id”,

      suppliername:”供应商名称”

    }

}

 usercount = (EditText) findViewById(R.id.usernumber);
 password = (EditText) findViewById(R.id.password);

下面代码中的usercount和password是我在界面中定义的两个EditText类型的控件。用来输入用户的账号和密码。

         AsyncHttpClient client = new AsyncHttpClient();
         String url = "http://xxx.xxx.xxx/MobileService/userLogin";
         // 使用RequestParams来向接口发送请求的参数,结合接口文档可以看出我要向服务器发送的参数为username和password
         RequestParams params = new RequestParams();
         params.put("username", usercount.getText().toString());
         params.put("password", password.getText().toString());
         // 请注意,在这里我是用的是AsyncHttpResponseHandler来进行网络处理,而没有使用JsonHttpResponseHandler来进行处理,原因在下面讲明。
         //另外需要注意的是这里一定要用post方式提交,而且在client.的时候千万不要忘记选择带参数params的post,否则你拿什么和服务器交流?我就翻过这样的错误。
         client.post(url, params, new AsyncHttpResponseHandler() {

             @Override
             public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
                 // TODO Auto-generated method stub
                 try {
                     // 从服务器中接收返回的数据,并进行字符集设置,返回的结果集放resultDate中,resultDate相当于一个容器,所有的返回信息都在其中。只要用过JSON解析出来返回值并逐个获取返回值就OK了。
                     // 在不要问我为什么这么使用,我也不知道。只清楚这么好用。
                     String resultDate = new String(arg2, "utf-8");
                     // 结合接口文档可以看出返回的结果都是单个的,没有返回的是集合或数组这样多个的情况,所以直接用JSONObject来接受返回值即可
                     JSONObject js = new JSONObject(resultDate);
                     // 将code、message、data解析出来。对于返回值是单个的而不是集合或数组的取值方式有两种。1:js.getJSONObject("xxx");2:js.getString("xxx");xxx代表任意String类型的字符串
                     //通过接口文档可以看出,返回值都是String类型的数据,所以我在这里选择了第二种取值方式,如果使用第一种会造成类型不匹配而导致程序错误。
                     String code = js.getString("code");
                     String message = js.getString("message");
                     String data = js.getString("data");
                     //对data中的数据进行进一步的解析,原理同上面一样
                     JSONObject jsonObject = new JSONObject(data);
                     String userid = jsonObject.getString("userid");
                     String supplier = jsonObject.getString("supplier");
                     String suppliername = jsonObject.getString("suppliername");
                     //1000代表状态码,表示登陆成功
                     if ("1000".equals(code)) {
                         //使用SharedPreferences将用户的账户和密码存储起来,关于SharedPreferences的存储知识请参考我的另外一篇文章
                         SharedPreferences sharedPreferences = getSharedPreferences(
                                 message, Activity.MODE_PRIVATE);
                         Editor editor = sharedPreferences.edit();
                         editor.putString("username", usercount.getText()
                                 .toString());
                         editor.putString("password", password.getText()
                                 .toString());
                         editor.commit();
                         Intent intent = new Intent(getApplicationContext(),
                                 MainActivity.class);
                         intent.putExtra("userid", userid.toString());
                         startActivity(intent);
                     } else {
                         Toast.makeText(getApplicationContext(), "账号或密码错误",
                                 Toast.LENGTH_LONG).show();
                     }
                 } catch (UnsupportedEncodingException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 } catch (JSONException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }

             }

             @Override
             public void onFailure(int arg0, Header[] arg1, byte[] arg2,
                     Throwable arg3) {
                 // TODO Auto-generated method stub
                 Toast.makeText(getApplicationContext(), "请检查网络!",
                         Toast.LENGTH_SHORT).show();
             }
         });
     

上面的代码是通过AsyncHttpResponseHandler()来处理服务器的返回值的,AsyncHttpClient中还有一个用来处理服务器的返回值,我看大多数博客都写的是这个JsonHttpResponseHandler()。

JsonHttpResponseHandler()来处理服务器返回值的代码如下:

         AsyncHttpClient client = new AsyncHttpClient();
         String url = "http://xxx.xxx.xxx/MobileService/userLogin";
         RequestParams params = new RequestParams();
         params.put("username", usercount.getText().toString());
         params.put("password", password.getText().toString());
         client.post(url, params, new JsonHttpResponseHandler() {
             @Override
             public void onSuccess(int statusCode, Header[] headers,
                     JSONObject response) {
                 // TODO Auto-generated method stub
                 super.onSuccess(statusCode, headers, response);
                 try {
                     JSONObject js = new JSONObject(response.toString());
                     String code = js.getString("code");

                     String message = js.getString("message");
                     String data = js.getString("data");

                     JSONObject jsonObject = new JSONObject(data);
                     String userid = jsonObject.getString("userid");
                     String supplier = jsonObject.getString("supplier");
                     String suppliername = jsonObject.getString("suppliername");

                     if ("1000".equals(code)) {
                         SharedPreferences sharedPreferences = getSharedPreferences(
                                 message, Activity.MODE_PRIVATE);
                         Editor editor = sharedPreferences.edit();
                         editor.putString("username", usercount.getText()
                                 .toString());
                         editor.putString("password", password.getText()
                                 .toString());
                         editor.commit();
                         Intent intent = new Intent(getApplicationContext(),
                                 MainActivity.class);
                         intent.putExtra("userid", userid.toString());
                         startActivity(intent);
                     } else {
                         Toast.makeText(getApplicationContext(), "账号或密码错误",
                                 Toast.LENGTH_LONG).show();
                     }

                 } catch (JSONException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
             }

             @Override
             public void onFailure(int statusCode, Header[] headers,
                     Throwable throwable, JSONArray errorResponse) {
                 // TODO Auto-generated method stub
                 super.onFailure(statusCode, headers, throwable, errorResponse);
                 Toast.makeText(getApplicationContext(), "请检查网络!",
                         Toast.LENGTH_SHORT).show();
             }
         });
     

请看第6行和第9行代码,第6行代码就是使用JsonHttpResponseHandler()来处理传回的数据的。第9行代码中的参数response就是上面特性中的第10条:使用JsonHttpResponseHandler类可以自动将响应结果解析为json格式。使用JsonHttpResponseHandler()虽然很方便,但是却存在着很大的问题。JsonHttpResponseHandler()在使用过程中有时莫名的出现请求不了服务器的情况,就是onSuccess和onFailure方法都进不去,这样就直接造成了程序无法正常使用。如果你不信你可以试试,明明前几分钟你使用JsonHttpResponseHandler()处理返回数据还好用呢,而你在这期间根本没有动过其中的代码,JsonHttpResponseHandler就莫名其妙的不好用了,而且原因不知道,无论你怎么调试都不成功。相反AsyncHttpResponseHandler()则根本不存在这样的问题。所以我就果断的放弃使用JsonHttpResponseHandler(),而采用AsyncHttpResponseHandler()来处理返回数据。当然AsyncHttpClient当中还封装了不少别的用来处理响应的方法,因为别的本人没有使用过,具体怎么样我也不知道。如果有使用过别的方法的朋友可以在下面留言告诉我,我们好相互学习。

对于接口返回值是数组或集合的形式有不会的朋友可以参照下面的代码,我就不解释了,反正是照着代码直接写肯定没有问题。

         AsyncHttpClient client = new AsyncHttpClient();
         String url = "http://xxx.xxx.xxx/MobileService/userLogin";
         RequestParams params = new RequestParams();
         params.add("userid", userid);
         client.post(url, params, new AsyncHttpResponseHandler() {

             @Override
             public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
                 // TODO Auto-generated method stub
                 try {
                     String resultDate = new String(arg2, "utf-8");
                     JSONObject js1 = new JSONObject(resultDate);
                     String code = js1.getString("code");
                     String message = js1.getString("message");
                     String data = js1.getString("data");
                     JSONObject js2 = new JSONObject(data);
                     if ("1000".equals(code)) {
                         String productlist = js2.getString("productlist");
                         JSONArray array = new JSONArray(productlist);//productlist返回的数据就是一个集合
                         //List<Map<String, Object>> arrays,这个在全局变量中进行声明。
               arrays = new ArrayList<Map<String, Object>>();
                         for (int i = 0; i < array.length(); i++) {
                             JSONObject js3 = array.getJSONObject(i);
                             String batchnumber = js3.getString("batchnumber");
                             HashMap<String, Object> map = new HashMap<String, Object>();
                             map.put("batchnumber", batchnumber);
                             arrays.add(map);
                         }
                         System.out.println("arrays:" + arrays);
                                             }

                 } catch (UnsupportedEncodingException e) {
                     Log.e("log_tag",
                             "Error parsing classname data" + e.toString());
                 } catch (JSONException e) {
                     // TODO Auto-generated catch block
                     Log.e("log_tag", "Request failed" + e.toString());
                 }
             }

             @Override
             public void onFailure(int arg0, Header[] arg1, byte[] arg2,
                     Throwable arg3) {
                 // TODO Auto-generated method stub
                 Toast.makeText(getApplicationContext(), "服务异常",
                         Toast.LENGTH_SHORT).show();
             }
         });
     

关于AsyncHttpClient网络框架的使用我的了解就是这么多了,关于JsonHttpResponseHandler()有时候不好用的问题如果谁知道怎么回事欢迎留言告诉我,鄙人感激不尽。希望这篇博客对大家有所帮助。

Android网络请求框架AsyncHttpClient实例详解(配合JSON解析调用接口)的更多相关文章

  1. android网络请求库volley方法详解

    使用volley进行网络请求:需先将volley包导入androidstudio中 File下的Project Structrue,点加号导包 volley网络请求步骤: 1. 创建请求队列     ...

  2. Python网络请求urllib和urllib3详解

    Python网络请求urllib和urllib3详解 urllib是Python中请求url连接的官方标准库,在Python2中主要为urllib和urllib2,在Python3中整合成了urlli ...

  3. Android 网络请求框架Retrofit

    Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的,OkHttp现在已经得到Google官方认可,大量的app都采用OkHttp ...

  4. Android网络请求框架

    本篇主要介绍一下Android中经常用到的网络请求框架: 客户端网络请求,就是客户端发起网络请求,经过网络框架的特殊处理,让后将请求发送的服务器,服务器根据 请求的参数,返回客户端需要的数据,经过网络 ...

  5. Android 网络请求框架android-async-http问题

    今天通过接口请求服务器的一些app数据,发现一个很奇怪的问题,请求一个链接的时候,通常在第一次请求发起的时候没有什么问题,能很快的拿到数据,但是 往后再去请求的时候就会等待很久,而且最后会请求失败,一 ...

  6. Android 网络请求框架

    1.okHttp 特点 简单.灵活.无连接.无状态 优势: 谷歌官方API在6.0之后在Android SDK中移除了HttpClient,然后他火了起来, 他支持SPDY(谷歌开发的基于TCP应用层 ...

  7. Android网络请求框架之Retrofit实践

    网络访问框架经过了从使用最原始的AsyncTask构建简单的网络访问框架(甚至不能称为框架),后来使用开源的android-async-http库,再到使用google发布的volley库,一直不懈的 ...

  8. Java/Android 网络请求框架/库

    Android 图片缓存框架  最上面的最优先 com.facebook.fresco:fresco:0.12.0                7.26.2016最新 Universal-Image ...

  9. (转)Java任务调度框架Quartz入门教程指南(三)任务调度框架Quartz实例详解深入理解Scheduler,Job,Trigger,JobDetail

    http://blog.csdn.net/zixiao217/article/details/53053598 首先给一个简明扼要的理解: Scheduler 调度程序-任务执行计划表,只有安排进执行 ...

随机推荐

  1. UPYUN云服务体验计划,阅读神器Kindle、LaCie移动硬盘、索尼大法充电宝、高大上极路由、UPYUN代金券等你拿!

    请看以下的“通关攻略”,分享你对云服务的“体验心得”,即可赢取绝佳的“通关宝藏”,阅读神器Kindle.LaCie移动硬盘.索尼大法充电宝.高大上极路由.UPYUN代金券等你拿!先来了解下UPYUN能 ...

  2. 设计模式的征途—3.抽象工厂(Abstract Factory)模式

    上一篇的工厂方法模式引入了工厂等级结构,解决了在原来简单工厂模式中工厂类职责太重的原则,但是由于工厂方法模式的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,从而增加系统开销.那么,我们应该 ...

  3. JVM 方法调用之动态分派

    1. 动态分派 一个体现是重写(override).下面的代码,运行结果很明显. public class App { public static void main(String[] args) { ...

  4. 图论算法-Dijkstra

    原理 Dijkstra是一个神奇的最短路径算法,它的优点在于它可以稳定的时间内求出一张图从某点到另一点的距离.它的工作原理非常简单,思路类似于广搜.在搜索前,将每个点的颜色设为白色,第一次将源点Ins ...

  5. java-cef嵌入基于Chrome内核浏览器,做页面爬虫(可以尽在ajax异步请求数据)

    1 CentOS 7.0 上安装和配置 VNC 服务器 2.1 2.1.1 首先,我们需要一个可用的桌面环境(X-Window),如果没有的话要先安装一个. 注意:以下命令必须以 root 权限运行. ...

  6. Hive篇之安装

    1,安装 hive的版本的选择,是选择内置的数据库保存元数据,还是用外部的mysql之类的数据库保存元数据,同时,如果使用外置的mysql,需要注意对mysql远程访问的配置. 再就是关于文件的配置了 ...

  7. 源码浅谈(一):java中的 toString()方法

    前言: toString()方法 相信大家都用到过,一般用于以字符串的形式返回对象的相关数据. 最近项目中需要对一个ArrayList<ArrayList<Integer>> ...

  8. hdu1198 Farm Irrigation 并查集

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1198 简单并查集 分别合并竖直方向和水平方向即可 代码: #include<iostream&g ...

  9. 记录——时间轮定时器(lua 实现)

    很长一段时间里,我错误的认识了定时器.无意中,我发现了“时间轮”这个名词,让我对定时器有了新的看法. 我错误的认为,定时器只需要一个 tick 队列,按指定的时间周期遍历队列,检查 tick 倒计时满 ...

  10. Android studio 断点技巧

    写代码不可避免有Bug,通常情况下除了日志最直接的调试手段就是debug:那么你的调试技术停留在哪一阶段呢?仅仅是下个断点单步执行吗?或者你知道 Evaluate Expression , 知道条件断 ...