首页 > 代码库 > android线程之 Handler与AsyncTask的应用

android线程之 Handler与AsyncTask的应用

做应用程序的开发的时候,我们程序员更多的关心的是线程。

    一个android应用程序开启后,默认开启一个主线程(大部分都和UI相关,所以又叫UI 线程).在UI线程上面运行的Avtivity组件,Service组件,BroadcastReceiver组件。

    用户操作主线程时,需要注意不允许在UI线程中做耗时的操作。比如:复杂的逻辑计算,休眠,联网,下载数据等都是耗时的操作。如果在UI主线程中做耗时的操作,一旦超过5秒,应用程序抛出异常,会报一个ANR(Application not respond)应用程序无法响应,紧接着退出。

 ANR错误的演示:
技术分享
技术分享
    那么耗时的操作在哪里运行呢?这个时候就需要使用线程了。
这时就不会产生以上的错误了。 如下所示:

技术分享

把耗时的工作都让子线程去做。
 
注意:Android中的控件只能被UI主线程操作,不能被其他线程操作,否则会有异常的产生】

Handler
     Handler负责在子线程中发送消息。
     Handler负责在主线程中接收消息。
     实现子线程和主线程间的通信。
 
Handler myHandler = new myHandler()
 
运行在主线程中的。主线程收到消息时,主线程通过handleMessage(msg)来接受消息


异步任务类AsyncTask

[1]Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler对象向UI线程发送消息,完成界面的更新,这种方式对整个界面的控制非常精细。
     但是也有缺点,例如代码臃肿,所以为了简化操作,Android 1.5 sdk 提供了一个工具类 AsyncTask(异步任务类),使得创建异步任务变的更加简单。
[2]一个异步任务的执行一般包括以下几个步骤:
     [1]execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。
     [2]onPreExecute(),在execute(Params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。
     [3]doInBackground(Params... params),在onPreExecute()完成后立即执行,用于执行较为耗时的操作,此方法将接受输入参数和返回计算结果。
        在执行过程中可以调用publicProgress(Progress...values)来更新进度信息。
     [4]onProgressUpdate(Progress... values),在调用publicProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。
     [5]onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将作为参数传递到此方法中,直接将结果显示到UI组件上。
  [3]在使用异步任务时,以下几点需要格外注意:
     [1]异步任务对象必须在UI主线程中创建。
     [2]不要手动调用onPreExcute(),doInBackground(Params... params), onProgressUpdate(Progress... values),onPostExecute(Result result)
     [3]不能再doInBackground(Params... params)中操作UI控件。

     异步任务类是对Handler的一个封装,原理都一样,创建类如下:
技术分享


相关参数:
技术分享



参数所代表的意义:
Params: 启动任务时输入的参数类型,如果不需要输入参数,则输入Viod
            该参数只能填写引用数据类型
Progress :后台任务执行的进度类型。

Result : 后台计算结果的类型

例如:  注意要把耗时的操作放在此方法中,注意:传入的参数所在的位置
技术分享



代码详细解析:
<span style="color:#660000;"> package com.hqyj.asyctask;
import android.os.AsyncTask;
import android.widget.TextView;

//Params    启动任务时的输入参数类型。注意:该参数只能填写引用数据类型,如果没有参数输入,填写Void
//Progress  后台任务执行的进度的类型。
//Result    后台计算结果的类型。
public class MyAsyncTask extends AsyncTask<Integer, Integer, String> {

 <span style="white-space: pre;">	</span>TextView tv;
 <span style="white-space: pre;">	</span>int count;
 
 <span style="white-space: pre;">	</span>public MyAsyncTask(TextView tv) {
<span style="white-space: pre;">	</span>  // TODO Auto-generated constructor stub
 <span style="white-space: pre;">	</span> this.tv = tv;
 <span style="white-space: pre;">	</span>}
 
<span style="white-space: pre;">	</span> //该方法被子线程调用
 <span style="white-space: pre;">	</span>//将耗时的操作放在该方法中
 <span style="white-space: pre;">	</span>@Override
 <span style="white-space: pre;">	</span>protected String doInBackground(Integer... params) {
 <span style="white-space: pre;">	</span> // TODO Auto-generated method stub
 
 <span style="white-space: pre;">	</span> while(count < params[0]){
 <span style="white-space: pre;">	</span>  //要求系统调用onProgressUpdate方法。
 <span style="white-space: pre;">	</span>  try {
 <span style="white-space: pre;">	</span>   Thread.sleep(1000);
 <span style="white-space: pre;">	</span>  } catch (InterruptedException e) {
 <span style="white-space: pre;">	</span>   // TODO Auto-generated catch block
  <span style="white-space: pre;">	</span>  e.printStackTrace();
  <span style="white-space: pre;">	</span> }
 <span style="white-space: pre;">	</span>  count++;
 <span style="white-space: pre;">	</span>  this.publishProgress(count);
 <span style="white-space: pre;">	</span> }
 
 
 <span style="white-space: pre;">	</span> return "任务结束";
 <span style="white-space: pre;">	</span>}

<span style="white-space: pre;">	</span> //该方法被UI主线程调用
<span style="white-space: pre;">	</span> //
 <span style="white-space: pre;">	</span>@Override
 <span style="white-space: pre;">	</span>protected void onProgressUpdate(Integer... values) {
 <span style="white-space: pre;">	</span> // TODO Auto-generated method stub
 <span style="white-space: pre;">	</span> super.onProgressUpdate(values);
 <span style="white-space: pre;">	</span> tv.setText(String.valueOf(values[0]));
 <span style="white-space: pre;">	</span>}
 
<span style="white-space: pre;">	</span> //异步任务启动时调用
 <span style="white-space: pre;">	</span>@Override
 <span style="white-space: pre;">	</span>protected void onPreExecute() {
 <span style="white-space: pre;">	</span> // TODO Auto-generated method stub
 <span style="white-space: pre;">	</span> super.onPreExecute();
 <span style="white-space: pre;">	</span> tv.setText("任务开始");
 <span style="white-space: pre;">	</span>}
 
 <span style="white-space: pre;">	</span>//异步任务结束时调用
 <span style="white-space: pre;">	</span>@Override
<span style="white-space: pre;">	</span> protected void onPostExecute(String result) {
 <span style="white-space: pre;">	</span> // TODO Auto-generated method stub
 <span style="white-space: pre;">	</span> super.onPostExecute(result);
  <span style="white-space: pre;">	</span>tv.setText(result);
}</span>


android线程之 Handler与AsyncTask的应用