AsyncTask的用法

本文介绍了OPhone 1.5版本引入的AsyncTask,一种用于解决匿名线程缺陷的机制。AsyncTask利用java.util.concurrent框架管理线程及任务执行,提供doInBackground、onPostExecute等方法简化UI更新操作。
匿名线程的方式是存在缺陷的:第一,线程的开销较大,如果每个任务都要创建一个线程,那么应用 程序的效率要低很多;第二,线程无法管理,匿名线程创建并启动后就不受程序的控制了,如果有很多个请求发送,那么就会启动非常多的线程,系统将不堪重负。 另外,前面已经看到,在新线程中更新UI还必须要引入handler,这让代码看上去非常臃肿。

        为了解决这一问题,OPhone在1.5版本引入了AsyncTask。AsyncTask的特点是任务在主线程之外运行,而回调方法是在主线程中执行, 这就有效地避免了使用Handler带来的麻烦。阅读AsyncTask的源码可知,AsyncTask是使用java.util.concurrent 框架来管理线程以及任务的执行的,concurrent框架是一个非常成熟,高效的框架,经过了严格的测试。这说明AsyncTask的设计很好的解决了 匿名线程存在的问题。

AsyncTask是抽象类,子类必须实现抽象方法doInBackground(Params... p) ,在此方法中实现任务的执行工作,比如连接网络获取数据等。通常还应该实现onPostExecute(Result r)方法,因为应用程序关心的结果在此方法中返回。需要注意的是AsyncTask一定要在主线程中创建实例。AsyncTask定义了三种泛型类型 Params,Progress和Result。

    * Params 启动任务执行的输入参数,比如HTTP请求的URL。
    * Progress 后台任务执行的百分比。
    * Result 后台执行任务最终返回的结果,比如String。


AsyncTask 的执行分为四个步骤,与前面定义的TaskListener类似。每一步都对应一个回调方法,需要注意的是这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。在任务的执行过程中,这些方法被自动调用。

    * onPreExecute() 当任务执行之前开始调用此方法,可以在这里显示进度对话框。
    * doInBackground(Params...) 此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress...)来更新任务的进度。
    * onProgressUpdate(Progress...) 此方法在主线程执行,用于显示任务执行的进度。
    * onPostExecute(Result) 此方法在主线程执行,任务执行的结果作为此方法的参数返回。


三个泛型参数: 
Param 任务执行器需要的数据类型 
Progress 后台计算中使用的进度单位数据类型 
Result 后台计算返回结果的数据类型 
有些参数是可以设置为不使用的,只要传递为Void型即可,比如AsyncTask</VOID,>

四个步骤: 
onPreExecute(),执行预处理,它运行于UI线程,可以为后台任务做一些准备工作,比如绘制一个进度条控件。 
doInBackground(Params…),后台进程执行的具体计算在这里实 现,doInBackground(Params…)是AsyncTask的关键,此方法必须重载。在这个方法内可以使用 publishProgress(Progress…)改变当前的进度值。 
onProgressUpdate(Progress…),运行于UI线程。如果在doInBackground(Params…)中 使用了publishProgress(Progress…),就会触发这个方法。在这里可以对进度条控件根据进度值做出具体的响应。 
onPostExecute(Result),运行于UI线程,可以对后台任务的结果做出处理,结果就是doInBackground(Params…)的返回值。此方法也要经常重载,如果Result为null表明后台任务没有完成(被取消或者出现异常)。

这4个方法都不能手动调用。而且除了doInBackground(Params…)方法,其余3个方法都是被UI线程所调用的,所以要求: 
1) AsyncTask的实例必须在UI thread中创建; 
2) AsyncTask.execute方法必须在UI thread中调用;

Task只能被执行一次,多次调用时将会出现异常,而且是不能手动停止。




 

package cn.asyn.rxm;



import android.app.Activity;

import android.os.AsyncTask;

import android.os.Bundle;

import android.util.Log;

import android.widget.TextView;



public class AsynctaskActivity extends Activity {

    TextView tv;

    final String TAG="AsyncTaskTest";

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        tv = (TextView) findViewById(R.id.label);

        new MyTask().execute(6, 12, 7);

 

    }

 

    class MyTask extends AsyncTask<Integer, Integer, Integer> {

 

        @Override

        protected void onPreExecute() {

            super.onPreExecute();

            Log.d(TAG, "onPreExecute()");

        }

 

        @Override

        protected Integer doInBackground(Integer... params) {

            Log.d(TAG, "doInBackground()");

            int p = 0;

            for (int index = 0; index < params.length; index++) {

                int num = params[index];

                for (int j = 0; j < num; j++) {

                    if (num - j <= 0) {

                        break;

                    }

                    p++;

                    publishProgress(p);

                    try {

                        Thread.sleep(500);

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                }

            }

            return p;

        }

 

        @Override

        protected void onProgressUpdate(Integer... progress) {

            Log.d(TAG, "onProgressUpdate()");

            tv.append("\nProgress: " + progress[0]);

        }

 

        @Override

        protected void onPostExecute(Integer result) {

            Log.d(TAG, "onPostExecute()");

            tv.append("\nFinished. Result: " + result);

        }

 

        @Override

        protected void onCancelled() {

            super.onCancelled();

            Log.d(TAG, "onCancelled()");

        }

    }

 

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值