`
stone02111
  • 浏览: 215225 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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、主要代码

 

public class HandlerDemo extends Activity implements OnScrollListener {
 
     private ListView mListView;
     LinearLayout loadingLayout;
     private Thread mThread;
     private ListViewAdapter adapter;
 
     private int startIndex = 1;// 从第1条开始
     private int size = 10;// 每次下载十条数据
     private List<News> newsList;
     List<Map<String, String>> data ;
 
     /*
      * 设置布局显示属性
      */
     private LayoutParams mLayoutParams = new LayoutParams(
             LinearLayout.LayoutParams.WRAP_CONTENT,
             LinearLayout.LayoutParams.WRAP_CONTENT);
 
     private LayoutParams ffLayoutParams = new LayoutParams(
             LinearLayout.LayoutParams.FILL_PARENT,
             LinearLayout.LayoutParams.FILL_PARENT);
 
     private ProgressBar progressBar;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         // TODO Auto-generated method stub
         super.onCreate(savedInstanceState);
         setContentView(R.layout.news_main);
         data=new ArrayList<Map<String, String>>();
         addView();
     }
 
     private void addView() {
         if (startIndex == 1) {
             newsList = new ArrayList<News>();
             newsList = getNewsList();
         }
         getdata(newsList);
         LinearLayout layout = new LinearLayout(this);
         layout.setOrientation(LinearLayout.HORIZONTAL);
         progressBar = new ProgressBar(this);
         layout.addView(progressBar, mLayoutParams);
         TextView textView = new TextView(this);
         textView.setText("加载中...");
         textView.setGravity(Gravity.CENTER_VERTICAL);
         layout.addView(textView, ffLayoutParams);
         layout.setGravity(Gravity.CENTER);
         loadingLayout = new LinearLayout(this);
         loadingLayout.addView(layout, mLayoutParams);
         loadingLayout.setGravity(Gravity.CENTER);
 
         // 得到一个ListView用来显示条目
         mListView = (ListView) findViewById(R.id.listView);
         mListView.addFooterView(loadingLayout);
         adapter = new ListViewAdapter();
         mListView.setAdapter(adapter);
         mListView.setOnScrollListener(this);
         mListView.setTextFilterEnabled(true);
     }
 
     @Override
     public void onScroll(AbsListView view, int firstVisibleItem,
             int visibleItemCount, int totalItemCount) {
         // TODO Auto-generated method stub
         if (firstVisibleItem + visibleItemCount == totalItemCount) {
             if (mThread == null || !mThread.isAlive()) {
                 mThread = new Thread() {
 
                     @Override
                     public void run() {
                         newsList = new ArrayList<News>();
                         newsList = getNewsList();
                         getdata(newsList);
                         Message msg = new Message();
                         msg.what = 1;
                         handler.sendMessage(msg);
                     }
                 };
                 mThread.run();
             }
         }
     }
     
     Handler handler = new Handler() {
 
         @Override
         public void handleMessage(Message msg) {
             // TODO Auto-generated method stub
             if (msg.what == 1) {
                 startIndex = startIndex + size;
                 Log.v("startindex", startIndex + "");
                 mListView.removeFooterView(loadingLayout);
                 mThread.stop();
                 adapter.count += size;
                 adapter.notifyDataSetChanged();
                 return;
             }
         }
     };
 
     class ListViewAdapter extends BaseAdapter {
         int count = 10;
 
         @Override
         public int getCount() {
             // TODO Auto-generated method stub
             return count;
         }
 
         @Override
         public Object getItem(int position) {
             // TODO Auto-generated method stub
             return position;
         }
 
         @Override
         public long getItemId(int position) {
             // TODO Auto-generated method stub
             return position;
         }
         
         @Override
         public View getView(int position, View convertView, ViewGroup parent) {
             // TODO Auto-generated method stub
             convertView = LayoutInflater.from(getApplicationContext()).inflate(
                     R.layout.news_item, null);
             TextView textView = (TextView) convertView
                     .findViewById(R.id.textNewsTitle);
             textView.setText((data.get(position)).get("title"));
             return convertView;
         }
     }
 
     @Override
     public void onScrollStateChanged(AbsListView view, int scrollState) {
         // TODO Auto-generated method stub
 
     }
 
     private List<Map<String, String>> getdata(List<News> list) {
 
         if (list == null)
             return null;
         for (News news : list) {
             Map<String, String> map = new HashMap<String, String>();
             map.put("title", news.getTitle());
             data.add(map);
         }
         return data;
     }
 
     /*
      * 获取网络数据 注:我是访问本机的一个新闻服务,使用asp.net技术来实现的
      * 这个是项目是一个基于android的资讯播报软件
      */
     private List<News> getNewsList() {
         String path = "http://10.0.2.2/getNewsList.aspx";
         String xmlStr = "<?xml version='1.0' encoding='utf-8'?><source><categoryIds>1,3,7</categoryIds><startIndex>"
                 + startIndex
                 + "</startIndex><detail>2</detail><count>"
                 + size
                 + "</count></source>";
         NewsConnector newsConnector = new NewsConnector();
         List<News> list = new ArrayList<News>();
         list = newsConnector.getNewsList(path, xmlStr);
         return list;
     }
 }
 

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、主要代码

 

@Override
     public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {
         // TODO Auto-generated method stub
         if(arg1+arg2==arg3)
         {
             if(!isloading)
             {
                 new myAsyncTask().execute(null);
             }
             else
             {
                 mListView.removeFooterView(loadingLayout);
             }
         }
     }
 
     @Override
     public void onScrollStateChanged(AbsListView arg0, int arg1) {
         // TODO Auto-generated method stub
         
     }
     
     private class myAsyncTask extends AsyncTask<Void, Void, Void>
     {
 
         @Override
         protected Void doInBackground(Void... params) {
             // TODO Auto-generated method stub
             
             newsList = new ArrayList<News>();
             newsList = getNewsList();
             getdata(newsList);
             return null;
             
         }
 
         @Override
         protected void onPostExecute(Void result) {
             // TODO Auto-generated method stub
             super.onPostExecute(result);
             adapter.count+=size;
             adapter.notifyDataSetChanged();
             startIndex+=size;
             isloading=false;
         }
 
         @Override
         protected void onPreExecute() {
             // TODO Auto-generated method stub
             super.onPreExecute();
             isloading=true;
         }
         
     }
 

 注:以上仅是和使用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变得比较复杂。

 
附件上截图

  

分享到:
评论

相关推荐

    ListView动态加载数据分页

    本文将深入探讨如何使用Handler+线程和AsyncTask两种方法来实现ListView的动态加载分页。 首先,我们来看看Handler+线程的实现方式。在主线程中,我们不能直接进行耗时操作,如网络请求或数据库查询,因为这会导致...

    Android实现listview动态加载数据分页的两种方法

    本文将详细介绍两种在Android中实现ListView动态加载数据分页的方法:Handler+线程和AsyncTask。 ### 1. Handler+线程方法 #### 1.1 Handler基础知识 Handler是Android中的一个关键组件,用于在不同的线程间通信...

    安卓listview相关相关-Listview分页加载数据.rar

    2. 异步加载:为了不影响用户体验,分页加载通常在后台线程执行,通过Handler或者AsyncTask等机制将数据同步回主线程。 3. 优化体验:在用户滚动时避免不必要的网络请求,例如设置一个缓冲区,只有当距离底部一定...

    listview实现动态加载

    "ListView实现动态加载"这个主题,涉及到的是如何高效地处理大量数据并根据用户滚动时动态加载更多内容的技术。动态加载通常用于节省内存,提高用户体验,避免一次性加载过多数据导致应用卡顿。 1. **ListView基础*...

    ListView多选框 动态加载 多线程刷新进度条

    动态加载,也称为分页加载,是处理大量数据的一种优化策略。在ListView滚动到底部时,我们会发送一个请求去加载更多的数据。这通常通过监听ListView的OnScrollListener事件来实现。在onScrollStateChanged()方法中,...

    listview的上拉加载下拉刷新+本地缓存+简单的头尾布局

    8. 异步处理:考虑到网络请求和数据库操作通常耗时,应当在后台线程执行,通过Handler、AsyncTask或者使用现代的Coroutines、Retrofit和Room库来实现异步数据加载和本地存储。 通过以上技术的结合,我们可以构建出...

    android listview分页加载的demo【源代码】

    - 为了不影响UI线程,加载更多数据的操作应在后台线程执行,如使用AsyncTask、Loader或者现代的Retrofit+RxJava组合。加载完成后,通过Handler或runOnUiThread回调到主线程更新ListView。 8. **缓存策略**: - ...

    listview异步加载.rar

    ListView是Android平台上常见的一种用于展示大量数据的视图组件,尤其在处理长列表时,它的异步加载机制显得尤为...在实际开发中,根据项目的具体需求和数据源的特性,灵活运用这些方法,可以实现流畅的ListView体验。

    Android开发之listview优化+图片异步加载缓存+避免图片显示闪烁

    2.1 **线程管理**:使用AsyncTask、Handler或第三方库如Volley、Retrofit等,在后台线程加载图片,避免阻塞主线程。 2.2 **图片库选择**:推荐使用成熟的图片加载库,如Glide、Picasso或 Fresco。这些库支持内存和...

    listView分页加载内容 异步加载

    1. **创建PagerListView类**:继承自ListView,添加滚动监听和数据加载功能。 2. **实现滚动监听**:在`onScroll()`方法中检查当前是否到达底部,如果达到,则启动异步加载。 3. **异步加载数据**:在`...

    Android Listview分页加载数据-IT计算机-毕业设计.zip

    可以使用AsyncTask、Handler、Retrofit+OkHttp等工具进行异步操作。 6. **数据更新**:在后台线程获取到新数据后,更新数据源,并调用Adapter的`notifyDataSetChanged()`方法通知ListView刷新视图。 7. **缓存机制...

    listview 分页加载,优化

    ListView是Android平台上常见的一种用于展示大量数据的视图组件,尤其在处理长列表时,它的分页加载和优化显得尤为重要。以下将详细讲解ListView的分页加载机制以及相关的优化策略。 1. **分页加载原理**: 分页...

    Listview中使用线程实现无限加载更多项目的功能

    2. **启动加载更多数据的线程**:在判断到用户滚动到底部后,启动一个新的线程,如AsyncTask或Handler,来执行获取新数据的任务。这一步要确保不在主线程中进行,以避免阻塞UI。 3. **异步加载数据**:在后台线程中...

    Android使用listview实现分页刷新(线程休眠模拟).zip

    本示例"Android使用listview实现分页刷新(线程休眠模拟)"主要探讨如何在ListView中实现分页加载功能,并通过线程休眠模拟网络延迟,增强用户体验。下面我们将详细讲解相关知识点。 1. **ListView基础**: - ...

    Android luncher拖动效果+listview下拉加载

    在Android开发中,"Android launcher拖动效果"和"listview下拉加载"是两个重要的功能模块,它们分别涉及到用户界面交互和数据加载优化。让我们深入探讨这些知识点。 首先,Android launcher是用户启动应用程序的主...

    异步加载及listview分页

    在Android开发中,异步...总之,异步加载和ListView分页是提升Android应用性能的关键技术,它们能确保应用在处理大量数据时保持响应性和流畅性。开发者需要理解这些概念,并熟练运用到项目中,以提供优秀的用户体验。

    ListView分页加载

    可以使用AsyncTask、Handler、Runnable配合Looper或者现代的协程(如Kotlin的Coroutines)来实现异步加载。 7. 分页策略:为了优化用户体验,可以考虑预加载机制,即在用户接近底部但还未到达时就开始加载下一页...

    Android ListView滚动到底部自动加载数据

    在Android开发中,ListView是一种常用的组件,用于展示大量的列表数据。`Android ListView滚动到底部自动加载数据`是一个常见的功能需求,特别是在实现无限滚动或者分页加载的场景下,比如社交媒体应用、电商应用的...

    异步加载网络资源并分页显示在ListView中

    综上所述,实现"异步加载网络资源并分页显示在ListView中"需要掌握Android多线程编程、网络请求、ListView的优化技巧、数据绑定以及图片加载和缓存策略。每个环节都需要精细设计和优化,以确保应用的高效稳定运行。...

Global site tag (gtag.js) - Google Analytics