使用AsyncHttpClient碰到的问题及解决方法

之前做一个项目,项目里面的布局是这样的:一个Viewpager,Viewpager里面有三个Fragment,在第二个Fragment里面有一个ListView,使用了BaseAdapter来显示item。当时因为图方便,把获取数据源mData的方法直接写在了adapter的构造方法里面,数据源通过syncHttpClient向后台请求参数获取。

大概的代码如下:

1 private LayoutInflater mInflater;

2 private static List<Map<String, Object>> mData = new ArrayList<Map<String, Object>>();

3 private RequestQueue queue;

4 private ImageLoader imageLoader;

5 private Context context;

6 private UserInfoEntity userInfoEntity;

7

8 public LessonEndingAdapter(Context context) {

9        this.context = context;

10        mInflater = LayoutInflater.from(context);

11        AuthCheck ac = new AuthCheck();

12        this.userInfoEntity = ac.getUserInfo(context);

13        queue = Volley.newRequestQueue(context);

14        imageLoader = new ImageLoader(queue, new BitmapCache());

15        init();

16 }

17 private void init() {

18        mData.clear();

19        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, "");

20        SyncHttpClient client = new SyncHttpClient();

21        client.get(url, new JsonHttpResponseHandler() {

22            @Override

23            public void onSuccess(int statusCode, Header[]     headers,JSONObject response) {

24        super.onSuccess(statusCode, headers, response);

25        if (statusCode == 200) {

26              processJsonData(response);

27        }

28    }

29   });

30 }

这里就不详细的讲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()方法,代码如下:

1 public void notifyChanged(){

2    synchronized(mObservers){

3      //since onChanged() is implemented by the app,it could do anything,including

4      //removing itself from{@link mObservers}-and that could cause problem if

5      //an iterator is used om the ArrayList{link mObservers}.

6      //to avoid such problems,just march thru the list in the reverse order.

7      for(int i = mObservers.size() - 1;!>=0;i--){

8        mObservers.get(i).onChanged();

9      }

10   }

11 }

从字面上看,就是一个循环,对每一个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,问题解决。当然,开发完APP也是需要进行全方位的检测:www.ineice.com

时间: 2024-08-25 18:19:30

使用AsyncHttpClient碰到的问题及解决方法的相关文章

安装ftp碰到的问题及解决方法

1   CRT显示乱码: 本地windows机器.修改SecureCRT的设置.找到"选项"->"会话选项"->"外观": *    字符编码设置为utf-8. *    字体设置,选择中文字体,例如新宋体. 2   查看ftp 服务是否启动: service vsftpd status 3 使 用chkconfig vsftpd on 设置为开机自动运行. 4  使用 service vsftpd stop 停止 使用service

初次使用VS2010基于C++开发项目碰到的问题及解决方法

1.将过去的工程用VS2010打开的时候.你有可能会遇到一大堆的警告:warning C4996. 比如:warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. 原因是Visual C++ 2005使用了更加安全的run-time library

项目中碰到的问题及解决方法记录

1. xml 3 字节的 UTF-8 序列的字节 3 无效 在STS中,将项目自动部署到tomcat 7并启动,发现启动过程中控制台打印出错误:3 字节的 UTF-8 序列的字节 3 无效 参考此文:https://my.oschina.net/tomJune/blog/673824 首先尝试删掉中文,发现无效,然后在pom.xml中尝试添加properties也不行,最后逐个xml把UTF-8改成了UTF8就好了,对就是去掉个减号而已. 2. 静态资源路径不正确 终于能启动tomcat了,但发

itunes彩铃DIY及碰到的问题和解决方法

挑选了几集头文字D重新看了遍,还依然是被满满地感动着.动画片中的一幕幕是懵懂青春的美好回忆,再次遇上这熟悉的美时便觉得这就是最真切的幸福.看完动画片心情满怀愉悦,然而却不想就此打住,片尾中那首“take me higher”前奏如此令自己动容,单曲循环之间依然不能够自已,突想何不将这前奏弄成自己的铃声,替换掉手机原带的,满大街都能够听到的铃声,每每有来电时还可愉悦自己!?想到就做吧,虽然不能更改那早已并病入膏肓的拖延症:) 先前也有DIY过铃声,但健忘得早已不知道如何下手,唯有问度娘.没啥耐性地

Android开发:StaggeredGridView瀑布流控件运行异常崩溃解决方法

StaggeredGridView是github上一个开源的瀑布流图片库,本文将分享集成StaggeredGridView时碰到的异常以及解决方法,StaggeredGriedView开源地址为:https://github.com/maurycyw/StaggeredGridView. StaggeredGriedViewDemo运行报错异常为: java.lang.RuntimeException: Unable to start activity  ComponentInfo{com.ex

Error:const char* 类型的实参和LPCWSTR类型的形参不兼容的解决方法。

在C++的Windows 应用程序中经常碰到这种情况. 解决方法: 加入如下转换函数: LPCWSTR stringToLPCWSTR(std::string orig) { size_t origsize = orig.length() + 1; const size_t newsize = 100; size_t convertedChars = 0; wchar_t *wcstring = (wchar_t *) malloc(sizeof(wchar_t) *(orig.length()

Excel碰到空行无法筛选排序解决方法

Excel碰到空行无法筛选排序解决方法 有时候excel可真心考人智商,一列中有空行,那么你就只能筛选排序首个空行前的内容了,解决方法来了,做个小记录,以防今后忘了. 1.在首列插入一列: 2.全选该列输入1,使用快捷键"Ctrl+回车键"填充整列: 3.选择首行,点击"数据-->筛选-->自动筛选",现在可以全部筛选及排序了 Excel碰到空行无法筛选排序解决方法,布布扣,bubuko.com

wampserver You don&#39;t have permission to access / on this server. 解决 方法(转,正好碰到这样的事情了就转下来)

最近在安装最近版wampserver 2.2 d时发现安装好后启动服务器,访问localhost显示You don't have permission to access / on this server. 而在目录127.0.0.1下可以访问. 造成这个问题的原因是Apache 的http.conf内的默认配置是 #   onlineoffline tag - don't remove Order Deny,Allow Deny from all Allow from 127.0.0.1 只允

转 Android学习笔记: 学习过程中碰到的一些问题及解决方法

在学习Android开发的过程中遇到了不少的问题,所幸的是最终经过上网查询都得到了解决.现在将我在学习Android开发过程中遇到的一些问题及解决的方法整理如下. 1.R.java不能实时更新 问题描述:在res文件中新增的变量不能在R.java中实时的显示出来. 解决方法:选择菜单栏的“Project”,勾选“Build Automatically”选项. 2.LogCat视窗没有显示 问题描述:在Eclipse的右下方没有显示LogCat视窗. 解决方法:选择菜单栏的“Windows”,再选