AsyncTask的使用

简介:

我们知道,Android不许在非UI线程中更新UI组件,所以Android提供了几种解决方案:

1. 使用Handler实现线程之间的通信。

2. Activity.runOnUiThread(Runnable)。

3. View.post(Runable)。

4.View.postDelayed(Runnable,long)。


后面的三种方式会导致编程略显繁琐,而异步任务(AsyncTask)可以简化这种操作。

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

· Params :启动任务执行的输入参数的类型。

· Progress: 后台任务完成的进度值的类型。

· Result: 后台执行任务完成后返回结果类型。


实现AsyncTask只需要三步:

1. 创建AsyncTask子类,并指定泛型类型,如果某个泛型参数不需要指定,则使用Void。

2. 根据需要实现AsyncTask方法:

·  doInBackground(Params...): 重写该方法就是后台线程将要完成的任务。 该方法可以调用publishProgress(Progress... values)方法更新任务的执行进度。

·  onProgressUpdate(Progress... values): 在doInBackground()方法中调用publishProgress()方法更新任务执行进度后,将会触发该方法。

·  onPreExecute(): 该方法将在后台执行耗时任务前被调用,通常该方法完成一些初始化的操作。比如在界面上显示等待进度框等。

·  onPostExecute(Result result): 当doInBackground()完成后,系统会自动调用onPostExecute()方法,并将doInBackground()方法的返回值传递给该方法。

3. 调用AsyncTask子类的实例的execute(Params... params)开始执行耗时任务。


使用AsyncTask的规则:

· 必须在UI线程中创建爱你AsyncTask的实例。

· 必须在UI线程中调用AsyncTask的execute方法。

· AsyncTask的回调方法有系统自动触发,程序员不应该主动去调用。

· 每个AsyncTask只能执行一次,多次调用将会引发异常。


示例:异步下载

public class AsyncTaskTest extends Activity
{
    private TextView show;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        show = (TextView) findViewById(R.id.show);
    }

    // 重写该方法,为界面的按钮提供事件响应方法
    public void download(View source) throws MalformedURLException
    {
        DownTask task = new DownTask(this);
        task.execute(new URL("http://www.crazyit.org/ethos.php"));
    }

    class DownTask extends AsyncTask<URL, Integer, String>
    {
        // 可变长的输入参数,与AsyncTask.exucute()对应
        ProgressDialog pdialog;

        // 定义记录已经读取行的数量
        int hasRead = 0;

        Context mContext;

        public DownTask(Context ctx)
        {
            mContext = ctx;
        }

        @Override
        protected String doInBackground(URL... params)
        {
            StringBuilder sb = new StringBuilder();
            try
            {
                URLConnection conn = params[0].openConnection();
                // 打开conn连接对应的输入流,并将它包装成BufferedReader
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
                String line = null;
                while ((line = br.readLine()) != null)
                {
                    sb.append(line + "\n");
                    hasRead++;
                    publishProgress(hasRead);
                }
                return sb.toString();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String result)
        {
            // 返回HTML页面的内容
            show.setText(result);
            pdialog.dismiss();
        }

        @Override
        protected void onPreExecute()
        {
            pdialog = new ProgressDialog(mContext);
            // 设置对话框的标题
            pdialog.setTitle("任务正在执行中");
            // 设置对话框 显示的内容
            pdialog.setMessage("任务正在执行中,敬请等待...");
            // 设置对话框不能用“取消”按钮关闭
            pdialog.setCancelable(false);
            // 设置该进度条的最大进度值
            pdialog.setMax(202);
            // 设置对话框的进度条风格
            pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            // 设置对话框的进度条是否显示进度
            pdialog.setIndeterminate(false);
            pdialog.show();
        }

        @Override
        protected void onProgressUpdate(Integer... values)
        {
            // 更新进度
            show.setText("已经读取了【" + values[0] + "】行!");
            pdialog.setProgress(values[0]);
        }
    }
}


上述实例中,我们在onPreExecute方法里初始化ProgressDialog弹出框; 在doInBackground()方法里进行耗时任务的操作(下载),接收的URL参数由UI线程传递过来task.execute(new URL("http://www.crazyit.org/ethos.php")); 耗时任务完成后,我们再onPostExecute方法里更新UI线程,并关闭了弹出框。 

此时注意,onProgressUpdate()方法主要用于更新进度,要想触发该方法,我们需要在doInBackground()方法里调用publishProgress()方法。

相关文章
|
5月前
|
Android开发
40. 【Android教程】AsyncTask:异步任务
40. 【Android教程】AsyncTask:异步任务
126 2
|
安全 Java Android开发
Android 中AsyncTask后台线程,异步任务的理解
Android 中AsyncTask后台线程,异步任务的理解
154 0
|
Java Android开发
AsyncTask
http://developer.android.youdaxue.com/reference/android/os/AsyncTask.html public abstract class AsyncTask extends Object java.lang.Object android.os.AsyncTask<Params, Progress, Result>
156 0
IntentService详解
IntentService是什么? 这篇文章是之前就写好的,一直没有整理出来,这几天有空正好整理发布一下。 我们知道Service可以让我们在后台处理一些事情,但是Service实际上也是主线程,所以执行长耗时任务时依然会ANR,只不过ANR触发时间要比前台长。一般我们会在Service中开启一个子线程去完成耗时任务。 而IntentService就是解决这个问题的,它是Service的一个抽象子类,需要实现onHandleIntent,代码在这个函数中执行。它与Service最大的不同就是默认开启一个子线程,而onHandleIntent就是在子线程中执行的。
151 0
|
Java Android开发
【Android 异步操作】AsyncTask 异步任务 ( FutureTask 模拟 AsyncTask 执行过程 | AsyncTask 执行过程回顾 | FutureTask 分析 )
【Android 异步操作】AsyncTask 异步任务 ( FutureTask 模拟 AsyncTask 执行过程 | AsyncTask 执行过程回顾 | FutureTask 分析 )
195 0
|
Java API 调度
【Android 异步操作】AsyncTask 异步任务 ( AsyncTask 异步任务执行方法 execute 方法相关源码解析 )
【Android 异步操作】AsyncTask 异步任务 ( AsyncTask 异步任务执行方法 execute 方法相关源码解析 )
169 0
|
Android开发 UED 数据格式
|
Android开发 UED 开发者