转载自http://blog.csdn.net/yaoyeyzq/article/details/6399351

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

  1 public class HandlerDemo extends Activity implements OnScrollListener {  2   3     private ListView mListView;  4     LinearLayout loadingLayout;  5     private Thread mThread;  6     private ListViewAdapter adapter;  7   8     private int startIndex = 1;// 从第1条开始  9     private int size = 10;// 每次下载十条数据 10     private List<News> newsList; 11     List<Map<String, String>> data ; 12  13     /* 14      * 设置布局显示属性 15      */ 16     private LayoutParams mLayoutParams = new LayoutParams( 17             LinearLayout.LayoutParams.WRAP_CONTENT, 18             LinearLayout.LayoutParams.WRAP_CONTENT); 19  20     private LayoutParams ffLayoutParams = new LayoutParams( 21             LinearLayout.LayoutParams.FILL_PARENT, 22             LinearLayout.LayoutParams.FILL_PARENT); 23  24     private ProgressBar progressBar; 25  26     @Override 27     protected void onCreate(Bundle savedInstanceState) { 28         // TODO Auto-generated method stub 29         super.onCreate(savedInstanceState); 30         setContentView(R.layout.news_main); 31         data=new ArrayList<Map<String, String>>(); 32         addView(); 33     } 34  35     private void addView() { 36         if (startIndex == 1) { 37             newsList = new ArrayList<News>(); 38             newsList = getNewsList(); 39         } 40         getdata(newsList); 41         LinearLayout layout = new LinearLayout(this); 42         layout.setOrientation(LinearLayout.HORIZONTAL); 43         progressBar = new ProgressBar(this); 44         layout.addView(progressBar, mLayoutParams); 45         TextView textView = new TextView(this); 46         textView.setText("加载中..."); 47         textView.setGravity(Gravity.CENTER_VERTICAL); 48         layout.addView(textView, ffLayoutParams); 49         layout.setGravity(Gravity.CENTER); 50         loadingLayout = new LinearLayout(this); 51         loadingLayout.addView(layout, mLayoutParams); 52         loadingLayout.setGravity(Gravity.CENTER); 53  54         // 得到一个ListView用来显示条目 55         mListView = (ListView) findViewById(R.id.listView); 56         mListView.addFooterView(loadingLayout); 57         adapter = new ListViewAdapter(); 58         mListView.setAdapter(adapter); 59         mListView.setOnScrollListener(this); 60         mListView.setTextFilterEnabled(true); 61     } 62  63     @Override 64     public void onScroll(AbsListView view, int firstVisibleItem, 65             int visibleItemCount, int totalItemCount) { 66         // TODO Auto-generated method stub 67         if (firstVisibleItem + visibleItemCount == totalItemCount) { 68             if (mThread == null || !mThread.isAlive()) { 69                 mThread = new Thread() { 70  71                     @Override 72                     public void run() { 73                         newsList = new ArrayList<News>(); 74                         newsList = getNewsList(); 75                         getdata(newsList); 76                         Message msg = new Message(); 77                         msg.what = 1; 78                         handler.sendMessage(msg); 79                     } 80                 }; 81                 mThread.run(); 82             } 83         } 84     } 85      86     Handler handler = new Handler() { 87  88         @Override 89         public void handleMessage(Message msg) { 90             // TODO Auto-generated method stub 91             if (msg.what == 1) { 92                 startIndex = startIndex + size; 93                 Log.v("startindex", startIndex + ""); 94                 mListView.removeFooterView(loadingLayout); 95                 mThread.stop(); 96                 adapter.count += size; 97                 adapter.notifyDataSetChanged(); 98                 return; 99             }100         }101     };102 103     class ListViewAdapter extends BaseAdapter {104         int count = 10;105 106         @Override107         public int getCount() {108             // TODO Auto-generated method stub109             return count;110         }111 112         @Override113         public Object getItem(int position) {114             // TODO Auto-generated method stub115             return position;116         }117 118         @Override119         public long getItemId(int position) {120             // TODO Auto-generated method stub121             return position;122         }123         124         @Override125         public View getView(int position, View convertView, ViewGroup parent) {126             // TODO Auto-generated method stub127             convertView = LayoutInflater.from(getApplicationContext()).inflate(128                     R.layout.news_item, null);129             TextView textView = (TextView) convertView130                     .findViewById(R.id.textNewsTitle);131             textView.setText((data.get(position)).get("title"));132             return convertView;133         }134     }135 136     @Override137     public void onScrollStateChanged(AbsListView view, int scrollState) {138         // TODO Auto-generated method stub139 140     }141 142     private List<Map<String, String>> getdata(List<News> list) {143 144         if (list == null)145             return null;146         for (News news : list) {147             Map<String, String> map = new HashMap<String, String>();148             map.put("title", news.getTitle());149             data.add(map);150         }151         return data;152     }153 154     /*155      * 获取网络数据 注:我是访问本机的一个新闻服务,使用asp.net技术来实现的156      * 这个是项目是一个基于android的资讯播报软件157      */158     private List<News> getNewsList() {159         String path = "http://10.0.2.2/getNewsList.aspx";160         String xmlStr = "<?xml version='1.0' encoding='utf-8'?><source><categoryIds>1,3,7</categoryIds><startIndex>"161                 + startIndex162                 + "</startIndex><detail>2</detail><count>"163                 + size164                 + "</count></source>";165         NewsConnector newsConnector = new NewsConnector();166         List<News> list = new ArrayList<News>();167         list = newsConnector.getNewsList(path, xmlStr);168         return list;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 2     public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) { 3         // TODO Auto-generated method stub 4         if(arg1+arg2==arg3) 5         { 6             if(!isloading) 7             { 8                 new myAsyncTask().execute(null); 9             }10             else11             {12                 mListView.removeFooterView(loadingLayout);13             }14         }15     }16 17     @Override18     public void onScrollStateChanged(AbsListView arg0, int arg1) {19         // TODO Auto-generated method stub20         21     }22     23     private class myAsyncTask extends AsyncTask<Void, Void, Void>24     {25 26         @Override27         protected Void doInBackground(Void... params) {28             // TODO Auto-generated method stub29             30             newsList = new ArrayList<News>();31             newsList = getNewsList();32             getdata(newsList);33             return null;34             35         }36 37         @Override38         protected void onPostExecute(Void result) {39             // TODO Auto-generated method stub40             super.onPostExecute(result);41             adapter.count+=size;42             adapter.notifyDataSetChanged();43             startIndex+=size;44             isloading=false;45         }46 47         @Override48         protected void onPreExecute() {49             // TODO Auto-generated method stub50             super.onPreExecute();51             isloading=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变得比较复杂。

附件上截图

更多相关文章

  1. 调用onSaveInstanceState(Bundle)保存数据的注意事项
  2. Android轻量级数据SparseArray详解
  3. Android(安卓)IntentService源码分析
  4. Android拾萃 - RxJava2之创建操作符及其demo
  5. Android线程学习 一
  6. Android(安卓)Framework系列之IPC(二)
  7. Adapter 要从源头开始适配
  8. Android读写XML(中)
  9. Android(安卓)CountDownTimer 倒计时器的简单使用

随机推荐

  1. Java时区转换与时间格式
  2. 8/人天,小记一次 JAVA(APP后台) 项目改造 .N
  3. VC6.0添加注释快捷键,类似Eclispe如此方便
  4. 用javascript进行拖拽2(转)
  5. 手低眼高 初学者学习Hibernate的方法
  6. java线程--volatile实现可见性
  7. 添加到arraylist中的列表时IndexOutOfBou
  8. 作为一只程序猿,我要说说IT业的研发工程师
  9. jQuery(JavaScript)获取文字(字符串)宽度(显示
  10. 变态跳台阶(java版)