Android AsyncTask 后监听异步加载完毕的动作详解
Android使用AsyncTask后监听异步加载完毕的动作
AsyncTask的使用方法网上有很多例子,使用起来也非常的方便。这里就不详细说具体的使用方法了,同学可以Google一下,很多。
场景模拟
当我们在加载一个列表的时候,比如GridView,这时候我们考虑到不阻塞UI的做法,一般会使用线程Thread、Timer或者使用AsyncTask,而这些操作都是在在后台另外开一个线程给我们找数据,具体得到的数据需要使用Handler去更新UI,AsyncTask也是一样使用到的Handler只是它将Handler封装在了onPostExecute执行操作中。而这一操作可能会产生一个问题,比如你有一个列表更新数据库使用到的是AsyncTask异步操作的方式更新UI,而你的需求是当我一进来这个列表就统计这个列表的数据的数量或者让某一行数据的状态为选中状态。传统做法是直接new一个AsyncTask类让它execute();之后会再操作UI。想法是对的,但有一个问题我们要注意到,因为它是异步加载数据的方式,而你的数据量比较多或许查找数据需要一定的时间的时候,这时使用AsyncTask执行异步加载后更新UI再操作UI对象,可能会报空指针。
这个问题的产生是,我们都知道代码的执行是自上而下执行,当你使用异步加载数据的时候,代码让你去执行异步操作就不管了(多线程),而继续会往下执行代码,你下面的代码就是操作列表里面的UI,这时可想而知,异步加载数据还没有结束还没有对你的UI进行更新,这些你的列表应该是空的,而操作一个空的列表就会报空指针。
分析问题
使用过AsyncTask的同学都知道一个异步加载数据最少要重写以下这两个方法:
doInBackground 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。
onPostExecute 相当于Handler处理UI的方式,在这里面可以使用在doInBackground得到的结果处理操作UI。
有必要的话你还得重写以下这三个方法,但不是必须的:
onProgressUpdate 可以使用进度条增加用户体验度。
onPreExecute 这里是最终用户调用Excute时的接口
onCancelled 用户调用取消时,要做的操作
根据上面的思路,可以看出,最终数据加载并显示出来这一系列的操作都在onPostExecute 这个方法里面,那么如何监听所有UI都己经在onPostExecute 里面处理完成了,再去执行我们自己要操作呢?
解决问题
这里给出我自己解决这一问题的思路,有更好想法的朋友欢迎跟贴共同探讨。
首先创建一个接口
privateinterfaceisLoadDataListener{ publicvoidloadComplete(); } 声明这一接口变量
privateisLoadDataListenerloadLisneter;
给接口赋值,得到接口对象
publicvoidsetLoadDataComplete(isLoadDataListenerdataComplete){ this.loadLisneter=dataComplete; }
之后在AsyncTask的onPostExecute处理UI完成后调用该接口,下面给出一个我以前项目使用到的AsyncTask类:
classloadGridAsyncTaskextendsAsyncTask<Integer,Integer,AppsAdapter>{ privateintpoindex; publicloadGridAsyncTask(intpositionindex){ this.poindex=positionindex; } @Override protectedAppsAdapterdoInBackground(Integer...params){ //TODOAuto-generatedmethodstub //mAppsModel.clear(); Cursortemp=dbHelper.queryPageById(poindex); loadPage(mApps,temp); temp.close(); returnnewAppsAdapter(STB.this,mAppsModel); } @Override protectedvoidonPostExecute(AppsAdapterresult){ gridViewExtitemGrid=(gridViewExt)viewFlipper .getChildAt(poindex); itemGrid.setColumnCount(pageColumnCount); itemGrid.setAdapter(result); if(loadLisneter!=null){ loadLisneter.loadComplete(); } } }
通过上面的代码,我们就得到一个数据加载完成后返回的接口,接下来的问题就是我们利用这个接口来处理我们的UI了,比如让某一UI选中,得到这个列表的UI数量等,看下面的代码:
newloadGridAsyncTask(1).execute(); setLoadDataComplete(newisLoadDataListener(){ @Override publicvoidloadComplete(){ //TODOAuto-generatedmethodstub //这里执行你要的操作,当UI更新完成后会自动调用这里面的代码} });
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!