【Android基础知识】【Android中的多线程asynctask】
首先来说一下AsyncTask,handler之后再说。
在网上收集到了不错的资料:
http://www.cnblogs.com/devinzhang/archive/2012/02/13/2350070.html
”
AsyncTask介绍
Android的AsyncTask比Handler更轻量级一些,适用于简单的异步处理。
首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。
Android为了降低这个开发难度,提供了AsyncTask。AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务。
AsyncTask直接继承于Object类,位置为android.os.AsyncTask。要使用AsyncTask工作我们要提供三个泛型参数,并重载几个方法(至少重载一个)。
AsyncTask定义了三种泛型类型 Params,Progress和Result。
- Params 启动任务执行的输入参数,比如HTTP请求的URL。
- Progress 后台任务执行的百分比。
- Result 后台执行任务最终返回的结果,比如String。
使用过AsyncTask 的同学都知道一个异步加载数据最少要重写以下这两个方法:
- doInBackground(Params…) 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。
- onPostExecute(Result) 相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回
有必要的话你还得重写以下这三个方法,但不是必须的:
- onProgressUpdate(Progress…) 可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。
- onPreExecute() 这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。
- onCancelled() 用户调用取消时,要做的操作
使用AsyncTask类,以下是几条必须遵守的准则:
- Task的实例必须在UI thread中创建;
- execute方法必须在UI thread中调用;
- 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法;
- 该task只能被执行一次,否则多次调用时将会出现异常;
“
下面这个例子最开始可以不用考虑进度条的事情。
package com.andyidea.demo; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; public class MainActivity extends Activity { Button download; ProgressBar pb; TextView tv; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); pb=(ProgressBar)findViewById(R.id.pb); tv=(TextView)findViewById(R.id.tv); download = (Button)findViewById(R.id.download); download.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { DownloadTask dTask = new DownloadTask(); dTask.execute(100); } }); } class DownloadTask extends AsyncTask<Integer, Integer, String>{ //后面尖括号内分别是参数(例子里是线程休息时间),进度(publishProgress用到),返回值 类型 @Override protected void onPreExecute() { //第一个执行方法 super.onPreExecute(); } @Override protected String doInBackground(Integer... params) { //第二个执行方法,onPreExecute()执行完后执行 for(int i=0;i<=100;i++){ pb.setProgress(i); publishProgress(i); try { Thread.sleep(params[0]); } catch (InterruptedException e) { e.printStackTrace(); } } return "执行完毕"; } @Override protected void onProgressUpdate(Integer... progress) { //这个函数在doInBackground调用publishProgress时触发,虽然调用时只有一个参数 //但是这里取到的是一个数组,所以要用progesss[0]来取值 //第n个参数就用progress[n]来取值 tv.setText(progress[0]+"%"); super.onProgressUpdate(progress); } @Override protected void onPostExecute(String result) { //doInBackground返回时触发,换句话说,就是doInBackground执行完后触发 //这里的result就是上面doInBackground执行后的返回值,所以这里是"执行完毕" setTitle(result); super.onPostExecute(result); } } }
另外的一个例子:
private class GetDataTask extends AsyncTask<Void, Void, List<Map<String,Object>>> { // 后台处理部分 @Override protected List doInBackground(Void... params) { // Simulates a background job. try { Thread.sleep(1000); } catch (InterruptedException e) { } // String str="Added after refresh...I add"; // return str; List<Map<String, Object>> mList = new ArrayList<Map<String, Object>>(); Map<String, Object> mMap = new HashMap<String, Object>(); mMap = new HashMap<String, Object>(); mMap.put("title", "G111"); mMap.put("info", "google 111"); mList.add(mMap); mMap = new HashMap<String, Object>(); mMap.put("title", "G112"); mMap.put("info", "google 112"); mList.add(mMap); mMap = new HashMap<String, Object>(); mMap.put("title", "G113"); mMap.put("info", "google 113"); mList.add(mMap); return mList; } //这里是对刷新的响应,可以利用addFirst()和addLast()函数将新加的内容加到LISTView中 //根据AsyncTask的原理,onPostExecute里的result的值就是doInBackground()的返回值 @Override protected void onPostExecute(List result) { //在头部增加新添内容 //通知程序数据集已经改变,如果不做通知,那么将不会刷新mListItems的集合 Toast.makeText(getApplicationContext(), "没有新新闻", Toast.LENGTH_SHORT).show(); // Call onRefreshComplete when the list has been refreshed. listview.onRefreshComplete(); super.onPostExecute(result);//这句是必有的,AsyncTask规定的格式 } }
这些例子学asynctask足够了。