ListView动态加载数据分页使用Handler+线程和AsyncTask两种方法.docx
- 文档编号:8617784
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:12
- 大小:110.21KB
ListView动态加载数据分页使用Handler+线程和AsyncTask两种方法.docx
《ListView动态加载数据分页使用Handler+线程和AsyncTask两种方法.docx》由会员分享,可在线阅读,更多相关《ListView动态加载数据分页使用Handler+线程和AsyncTask两种方法.docx(12页珍藏版)》请在冰豆网上搜索。
ListView动态加载数据分页使用Handler+线程和AsyncTask两种方法
ListView动态加载数据分页(使用Handler+线程和AsyncTask两种方法)
在android开发中,经常需要使用数据分页,比如要实现一个新闻列表的显示,或者博文列表的显示,不可能第一次加载就展示出全部,这就需要使用分页的方法来加载数据,在android中Handler经常用来在耗时的工作中,它接收子线程发送的数据,并使用数据配合更新UI,AsyncTask是在一个线程中执行耗时操作然后把结果传给UI线程,不需要你亲自去管理线程和句柄。
一、使用Handler+线程方法
1、基础知识
Handler在android系统中,主要负责发送和接收消息,它的用途主要有以下两种:
(1)按照计划来处理一个消息(sendMessage(Message)方法)或者执行某个runnable实例(post(Runnable)方法)
(2)把其他的线程对象放入消息队列中,避免线程冲突。
消息的发送通过post(Runnable),postAtTime(Runnable,long),postDelayed(Runnable,long),sendEmptyMessage(int),sendMessage(Message),sendMessageAtTime(Message,long)和sendMessageDelayed(Message,long)方法完成。
对于postXXX方法通过Runnable对象给消息队列,并在消息队列到达后被调用。
对于sendMessageXXX方法,则传递一个包含message对象,该对象可以被Handler类的handlerMessage(Message)方法处理。
2、主要代码
1publicclassHandlerDemoextendsActivityimplementsOnScrollListener{
2
3privateListViewmListView;
4LinearLayoutloadingLayout;
5privateThreadmThread;
6privateListViewAdapteradapter;
7
8privateintstartIndex=1;//从第1条开始
9privateintsize=10;//每次下载十条数据
10privateList
11List
12
13/*
14*设置布局显示属性
15*/
16privateLayoutParamsmLayoutParams=newLayoutParams(
17LinearLayout.LayoutParams.WRAP_CONTENT,
18LinearLayout.LayoutParams.WRAP_CONTENT);
19
20privateLayoutParamsffLayoutParams=newLayoutParams(
21LinearLayout.LayoutParams.FILL_PARENT,
22LinearLayout.LayoutParams.FILL_PARENT);
23
24privateProgressBarprogressBar;
25
26@Override
27protectedvoidonCreate(BundlesavedInstanceState){
28//TODOAuto-generatedmethodstub
29super.onCreate(savedInstanceState);
30setContentView(R.layout.news_main);
31data=newArrayList
32addView();
33}
34
35privatevoidaddView(){
36if(startIndex==1){
37newsList=newArrayList
38newsList=getNewsList();
39}
40getdata(newsList);
41LinearLayoutlayout=newLinearLayout(this);
42layout.setOrientation(LinearLayout.HORIZONTAL);
43progressBar=newProgressBar(this);
44layout.addView(progressBar,mLayoutParams);
45TextViewtextView=newTextView(this);
46textView.setText("加载中...");
47textView.setGravity(Gravity.CENTER_VERTICAL);
48layout.addView(textView,ffLayoutParams);
49layout.setGravity(Gravity.CENTER);
50loadingLayout=newLinearLayout(this);
51loadingLayout.addView(layout,mLayoutParams);
52loadingLayout.setGravity(Gravity.CENTER);
53
54//得到一个ListView用来显示条目
55mListView=(ListView)findViewById(R.id.listView);
56mListView.addFooterView(loadingLayout);
57adapter=newListViewAdapter();
58mListView.setAdapter(adapter);
59mListView.setOnScrollListener(this);
60mListView.setTextFilterEnabled(true);
61}
62
63@Override
64publicvoidonScroll(AbsListViewview,intfirstVisibleItem,
65intvisibleItemCount,inttotalItemCount){
66//TODOAuto-generatedmethodstub
67if(firstVisibleItem+visibleItemCount==totalItemCount){
68if(mThread==null||!
mThread.isAlive()){
69mThread=newThread(){
70
71@Override
72publicvoidrun(){
73newsList=newArrayList
74newsList=getNewsList();
75getdata(newsList);
76Messagemsg=newMessage();
77msg.what=1;
78handler.sendMessage(msg);
79}
80};
81mThread.run();
82}
83}
84}
85
86Handlerhandler=newHandler(){
87
88@Override
89publicvoidhandleMessage(Messagemsg){
90//TODOAuto-generatedmethodstub
91if(msg.what==1){
92startIndex=startIndex+size;
93Log.v("startindex",startIndex+"");
94mListView.removeFooterView(loadingLayout);
95mThread.stop();
96adapter.count+=size;
97adapter.notifyDataSetChanged();
98return;
99}
100}
101};
102
103classListViewAdapterextendsBaseAdapter{
104intcount=10;
105
106@Override
107publicintgetCount(){
108//TODOAuto-generatedmethodstub
109returncount;
110}
111
112@Override
113publicObjectgetItem(intposition){
114//TODOAuto-generatedmethodstub
115returnposition;
116}
117
118@Override
119publiclonggetItemId(intposition){
120//TODOAuto-generatedmethodstub
121returnposition;
122}
123
124@Override
125publicViewgetView(intposition,ViewconvertView,ViewGroupparent){
126//TODOAuto-generatedmethodstub
127convertView=LayoutInflater.from(getApplicationContext()).inflate(
128R.layout.news_item,null);
129TextViewtextView=(TextView)convertView
130.findViewById(R.id.textNewsTitle);
131textView.setText((data.get(position)).get("title"));
132returnconvertView;
133}
134}
135
136@Override
137publicvoidonScrollStateChanged(AbsListViewview,intscrollState){
138//TODOAuto-generatedmethodstub
139
140}
141
142privateList
143
144if(list==null)
145returnnull;
146for(Newsnews:
list){
147Map
148map.put("title",news.getTitle());
149data.add(map);
150}
151returndata;
152}
153
154/*
155*获取网络数据注:
我是访问本机的一个新闻服务,使用技术来实现的
156*这个是项目是一个基于android的资讯播报软件
157*/
158privateList
159Stringpath="http:
//10.0.2.2/getNewsList.aspx";
160StringxmlStr="
xmlversion='1.0'encoding='utf-8'?
>
161+startIndex
162+"
163+size
164+"";
165NewsConnectornewsConnector=newNewsConnector();
166List
167list=newsConnector.getNewsList(path,xmlStr);
168returnlist;
169}
170}
3、小结
ListView使用Handler+线程方式来动态加载数据的步骤如下:
1.先初始化页面(如:
加载第一页数据)
2.在接收某个事件的消息之后(以上代码是onScroll事件),启动线程(线程完成下载数据,并发送消息给handler)
3.handler接收到消息后更新界面,显示数据。
二、使用AsyncTask方法
1、基础知识
AsyncTask也是android提供的一个为了不能阻塞主线程的一个类,AsyncTask定义了三种泛型类型Params、Progress和Result,Params启动任务执行输入参数,比如http请求的url和参数,Progress后台执行任务的百分比,后台执行最终返回的结果。
AsyncTask的执行分为四个步骤,每一步都对应都对应一个回调方法,开发者需要实现一个或者几个方法,在任务的执行过程中,这些方法会自动调用。
onPreExecute(),在执行后台耗时操作前被调用,可以在执行此方法中做一些ui操作,比如显示一个进度条等
doInBackground(Params...),这个方法在执行onPreExecute()后执行,这个方法完成耗时工作,比如下载等。
onProgressUpdate(Progress...),UI线程通过此方法获取任务的完成的情况,比如完成的任务的百分比。
onPostExecute(Result),这个方法在耗时工作完成后被调用。
UI线程调用此方法获取结果。
注意:
在使用AsyncTask类,有几条准则需要遵守
(1)、Task的实例必须在UI线程中创建
(2)、execute方法必须在UI线程中调用
(3)、不要手动调用以上四个方法
(4)、这个任务只执行一次(如果执行第二次将会抛出异常)
2、主要代码
1@Override
2publicvoidonScroll(AbsListViewarg0,intarg1,intarg2,intarg3){
3//TODOAuto-generatedmethodstub
4if(arg1+arg2==arg3)
5{
6if(!
isloading)
7{
8newmyAsyncTask().execute(null);
9}
10else
11{
12mListView.removeFooterView(loadingLayout);
13}
14}
15}
16
17@Override
18publicvoidonScrollStateChanged(AbsListViewarg0,intarg1){
19//TODOAuto-generatedmethodstub
20
21}
22
23privateclassmyAsyncTaskextendsAsyncTask
24{
25
26@Override
27protectedVoiddoInBackground(Void...params){
28//TODOAuto-generatedmethodstub
29
30newsList=newArrayList
31newsList=getNewsList();
32getdata(newsList);
33returnnull;
34
35}
36
37@Override
38protectedvoidonPostExecute(Voidresult){
39//TODOAuto-generatedmethodstub
40super.onPostExecute(result);
41adapter.count+=size;
42adapter.notifyDataSetChanged();
43startIndex+=size;
44isloading=false;
45}
46
47@Override
48protectedvoidonPreExecute(){
49//TODOAuto-generatedmethodstub
50super.onPreExecute();
51isloading=true;
52}
53
54}
注:
以上仅是和使用Handler+线程方法不同的代码,建议下载源码,了解详细代码
3、小结
ListView使用AsyncTask方法动态加载数据的方法如下:
1.和handler一样初始化页面(如:
加载第一页)
2.在接收某个事件的消息之后(以上代码是onScroll事件),创建一个新的异步任务,并开始执行
3.耗时工作完成后,开始更新UI
三、总结
使用Handler+线程和使用AsyncTask方法进行ListView动态加载的比较
Handler+线程方式:
在使用Handler方式时,它涉及Handler、Thread、Message、Looper四个对象,在执行的流程如下:
主线程启动一个Thread,这个Thread执行耗时操作,耗时操作完成后,生成一个Message,Looper读取Message并传递给Hander,Handler接收Message并更新响应的UI。
因为Looper在一个message处理完,才会读下一条,如果发生多个Message就会形成一个消息队列,所以它对多个后台操作比较清晰,明朗。
但对于单个message来讲显得代码比较多,过于复杂。
AsyncTask方式:
AsyncTask继承自Object,是android提供的轻量级的异步类。
并提供了一个方法来获取任务的执行进度(可以根据它来更新UI),最后会把结果返回在主线程。
这个方式的比较简单,而且可以清楚的看到耗时任务执行的进度。
但是对于多个异步操作同时进行,并更新UI变得比较复杂。
附件上截图
----转载请注明出处谢谢!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ListView 动态 加载 数据 分页 使用 Handler 线程 AsyncTask 方法