使用AsyncHttpClient碰到的问题及解决方法
来源:互联网 发布:超市软件安装视频 编辑:程序博客网 时间:2024/05/16 18:52
之前做一个项目,项目里面的布局是这样的:一个Viewpager,Viewpager里面有三个Fragment,在第二个Fragment里面有一个ListView,使用了BaseAdapter来显示item。当时因为图方便,把获取数据源mData的方法直接写在了adapter的构造方法里面,数据源通过syncHttpClient向后台请求参数获取。
大概的代码如下:
private LayoutInflater mInflater;private static List<Map<String, Object>> mData = new ArrayList<Map<String, Object>>();private RequestQueue queue;private ImageLoader imageLoader;private Context context;private UserInfoEntity userInfoEntity;public LessonEndingAdapter(Context context) { this.context = context; mInflater = LayoutInflater.from(context); AuthCheck ac = new AuthCheck(); this.userInfoEntity = ac.getUserInfo(context); queue = Volley.newRequestQueue(context); imageLoader = new ImageLoader(queue, new BitmapCache()); init();}private void init() { mData.clear(); String url = Codes.URL_ROOT + "/lesson/studied.api?" + "userid="+ context.getSharedPreferences(Codes.USERINFO, 0).getInt(Codes.USERID, 0) + "&token="+ context.getSharedPreferences(Codes.USERINFO, 0).getString(Codes.TOKEN, ""); SyncHttpClient client = new SyncHttpClient(); client.get(url, new JsonHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers,JSONObject response) { super.onSuccess(statusCode, headers, response); if (statusCode == 200) { processJsonData(response); } } });}
这里就不详细的讲SyncHttpClient的用法了,只说说我在使用过程中碰到的一些问题和解决办法。
当时我在init()中用的是AsyncHttpClient(代码里面是SyncHttpCilent),没在意AsyncHttpClient和SyncHttpClient的区别,随意挑了前者,结果问题就出现了:
第一次init没有问题,但是当init操作执行几次后,页面变成了空白一片,listView中的item都消失了。
我在adapter的init(),getView(),getCount()中都写了Log,发现init()方法中的mData成功获取了数据,但是getCount方法中显示item数目为0,而getView中的log更是直接就没打印出来。一般来说,在一个类中,代码的执行顺序肯定是:变量声明->构造方法->其他方法,所以init()应该是在getCount和getView之前执行的。现在数据获取到了,但是却没有在布局中显示出来,惯性思维下,我觉得应该是adapter出现了问题。
我先从adapter的notifyDataSetChanged()方法入手,一步步点进去,最后进入notifyChanged()方法,代码如下:
从字面上看,就是一个循环,对每一个item进行判断是否改变,若改变的话对布局进行修改。但现在的问题是getCount为0,也就是说并未进行这个循环,通过Log打印的顺序,我对getView中Log没打出来的问题有了大致的猜想:
在adapter中方法执行的顺序为:构造方法->getCount->getView,其他方法在adapter中并不是必不可少的,暂且不论。当listView绑定了一个adapter时,程序会执行构造方法,然后执行getCount(),getCount()会重复执行几遍,当getCount方法不为0时,执行getView方法。若getCount()一直为0,那么就不执行getView(),布局自然而然就不会显示出来。
现在的问题就是,数据取到了(mData有数据),但是getCount为什么一直为0呢?我想来想去也只有从第三方类库SyncHttpClient入手了。在网上查了一下SyncHttpClient和AsyncHttpClient的特性,发现字面意思已经表达的很清楚了:sync->同步,async->异步……也就是说,当用AsyncHttpClient时,程序会自动新开一个线程,数据获取在一个线程,而adapter中的getCount又在另一个线程,两者的进度是无法把握的。结果很明显了,虽然是init()方法先执行,但是由于AsyncHttpCilent新开了一个线程,导致在请求参数的过程中,getCount()也已经开始执行,AsyncHttpClient是一个较为耗时的操作,所以每次getCount都先于client.get执行完毕,这就解释了为什么getCount一直为0而mData又不为空了!
既然发现了问题那就很好解决了,最简单的方法就是把AsyncHttpClient改成SyncHttpClient。但是这样做性能很差,这就失去了异步操作存在的意义了。我的方法是在AsynHttpClient方法的末尾,即数据取完之后,加一个adapter.notifyDataSetChanged(),这时程序会自动再次执行getCount,很显然这次的getCount就不为0了,紧接着就执行getView显示布局,ok,问题解决。
- 使用AsyncHttpClient碰到的问题及解决方法
- 使用AsyncHttpClient碰到的问题及解决方法
- 使用AsyncHttpClient碰到的问题及解决方法
- 使用AsyncHttpClient碰到的问题及解决方法
- shell 使用中碰到的问题及解决方法
- 使用Caffe时碰到的问题及解决方法
- 安装ftp碰到的问题及解决方法
- 第一次使用jdbc连接postgre数据库碰到的问题及解决方法
- 初次使用VS2010基于C++开发项目碰到的问题及解决方法
- 初次使用VS2010基于C++开发项目碰到的问题及解决方法
- 初次使用VS2010基于C++开发项目碰到的问题及解决方法
- 初次使用VS2010基于C++开发项目碰到的问题及解决方法
- 初次使用VS2010基于C++开发项目碰到的问题及解决方法
- 初次使用VS2010基于C++开发项目碰到的问题及解决方法
- 初次使用VS2010基于C++开发项目碰到的问题及解决方法
- android 自定义键盘碰到的问题及解决方法
- 二级列表碰到的部分问题及解决方法
- word使用样式常碰到的问题和解决方法参考
- 线程重用——线程池的基本原理
- 一些小功能的累积
- Hibernate Merge (Illegal attempt to associate a collection with two open sessions)
- leetcode Binary Tree Zigzag Level Order Traversal
- IntelliJ Idea 常用快捷键列表
- 使用AsyncHttpClient碰到的问题及解决方法
- CodeForces 589G Hiring(树状数组)
- mysql事务回滚的问题
- 如何定制支持用户自定义boot参数的基于debian os的live cd
- POST方式上传文件
- 前端开发中的性能那点事(一)巧用xdebug
- Nginx下载和编译安装
- JS保留两位小数
- html5+javascript+css3实现下拉列表以及折叠功能