异步任务(AsyncTask)

为了解决新线程不能更新UI组件的问题,Android提供了如下几种解决方案:

  • 使用Handler实现线程之间的通信
  • Activity.runOnUiThread(Runable)
  • View.post(Runable)
  • View.postDelayed(Runable,long)

前面我们已经知道了如何使用Handler,后三种方式可能导致编程略显繁琐,而异步任务则可简化这种操作。

 

AsyncTask<Params, Progress, Result>是抽象类,定义了下面三种泛型类型:

  • Params: 启动任务执行的输入参数的类型。
  • Progress: 后台任务完成的进度值的类型。
  • Result:  后台执行任务完成后返回结果的类型。

 

使用AsyncTask只要如下三步:

  1. 创建AsyncTask的子类,并为三个泛型类型的参数指定类型,如果某个泛型类型不需要指定参数,则指定为void
  2. 根据需要,实现AsyncTask的方法
  3. 调用AsyncTask子类的实例的execute(Parmas… params)开始执行耗时任务。

 

使用AsyncTask 需要注意一下几点:

  • 必须在UI线程中创建AsyncTask的实例
  • 必须在UI线程中调用AsyncTaskexcute方法
  • AsyncTaskonPreExecute()onPostExecute(Result result) doInBackground(Params… params)onProgressUpdate(Progress… values)方法,不应该有程序员代码调用,而是由Android系统负责调用。
  • 每个AsyncTask只能被执行一次,多次调用会出现异常。

 

实例:

//布局文件中仅有一个按钮和一个文本框,按钮负责触发download任务。

 

  1 public class MainActivity extends AppCompatActivity {
  2 
  3  
  4 
  5     private TextView show;
  6 
  7  
  8 
  9     @Override
 10 
 11     protected void onCreate(Bundle savedInstanceState) {
 12 
 13         super.onCreate(savedInstanceState);
 14 
 15         setContentView(R.layout.activity_main);
 16 
 17         show = (TextView) findViewById(R.id.show);
 18 
 19  
 20 
 21     }
 22 
 23  
 24 
 25     public void download(View source) throws MalformedURLException{
 26 
 27         DownTask task = new DownTask(this);
 28 
 29         task.execute(new URL("http://www.crazyit.org/ethos.php"));
 30 
 31     }
 32 
 33  
 34 
 35     private class DownTask extends AsyncTask<URL, Integer, String> {
 36 
 37         ProgressDialog pdialog;
 38 
 39         int hasRead = 0;
 40 
 41         Context mContext;
 42 
 43         public DownTask(Context ctxt){
 44 
 45             mContext = ctxt;
 46 
 47         }
 48 
 49  
 50 
 51         @Override
 52 
 53         protected String doInBackground(URL... params) {
 54 
 55             StringBuilder sb = new StringBuilder();
 56 
 57             try{
 58 
 59             URLConnection conn = params[0].openConnection();
 60 
 61             BufferedReader br = new BufferedReader(
 62 
 63                     new InputStreamReader(conn.getInputStream(),"utf-8"));
 64 
 65             String line = null;
 66 
 67             while ((line = br.readLine()) != null){
 68 
 69                 sb.append(line + "\n");
 70 
 71                 hasRead++;
 72 
 73                 publishProgress(hasRead);
 74 
 75             }
 76 
 77             return sb.toString();
 78 
 79             }
 80 
 81             catch (Exception e){
 82 
 83                 e.printStackTrace();
 84 
 85             }
 86 
 87             return null;
 88 
 89         }
 90 
 91  
 92 
 93         @Override
 94 
 95         protected void onPostExecute(String s) {
 96 
 97             show.setText(s);
 98 
 99             pdialog.dismiss();
100 
101         }
102 
103  
104 
105         @Override
106 
107         protected void onPreExecute() {
108 
109             pdialog = new ProgressDialog(mContext);
110 
111             pdialog.setTitle("任务执行中");
112 
113             pdialog.setMessage("任务正在进行中,敬请等待...");
114 
115             pdialog.setCancelable(false);
116 
117             pdialog.setMax(202);
118 
119             pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
120 
121             pdialog.setIndeterminate(false);
122 
123             pdialog.show();
124 
125         }
126 
127  
128 
129         @Override
130 
131         protected void onProgressUpdate(Integer... values) {
132 
133             show.setText("已经读取了【" + values[0] + "】行!");
134 
135             pdialog.setProgress(values[0]);
136 
137         }
138 
139     }
140 
141 }

 

 

注意该实例使用了网络功能,因此需要在AndroidManifest.xml中声明

<uses-permissionandroid:name="android.permission.INTERNET"/>

 

  • doInBackground(Paramas... ): 重写该方法就是后台线程将完成的任务,该方法可以调用publishProgress来显示任务完成的进度。
  • onPostExecute(Result result): doInBackground完成后系统会自动调用这个方法,并将doInBackground方法的返回值传给该方法。
  • onPreExecute(): 该方法将在执行后台耗时任务的前被调用,通常该方法用于完成一些初始化工作,比如显示进度条。
  • onProgressUpdate(Progress... values): doInBackground 中调用publishProgress 后触发。

 

转载于:https://www.cnblogs.com/NeonCowboy/p/5495603.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值