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()方法。

时间: 2024-10-27 22:45:59

AsyncTask的使用的相关文章

对AsyncTask进行封装,简化繁琐的异步操作

对于android的异步操作,往往有二种方法给予我们选择.      一:Thread+Handler      二:  AsyncTask        对于二者的相同与异同点,这里并不去进行比较.这里提供一种简化异步操作的方法,供大家参考学习.         代码参考自AndEngine,不过我对它做了一定的修改,让它更适合自己目前项目的开发,感谢open source 能够让我们去学习和阅读那么多优秀的代码.        废话不多说,代码如下:        CallEarliest<

Android中用HandlerThread模拟AsyncTask功能(ThreadTask)

前言 AsyncTask是个好东西,能处理绝大多数应用线程和更新UI的任务,由于其内部使用了静态线程池,如果你有一堆异步任务(例如全局定时更新数据.同一个Activity中多个AsyncTask同时执行)其中有不能马上执行完的情况(例如网络请求超时),那就糟了,其他任务都还等着呢,就会出现任务卡住的情况.此时就需要直接上Thread了,这里参考AsyncTask的API封装了一个ThreadTask,便于必要时代码替换,欢迎交流! 农民伯伯: http://over140.cnblogs.com

Android AsyncTask与handler

本文主要讲解下AsyncTask的使用以及Handler的应用 首先,我们得明确下一个概念,什么是UI线程.顾名思义,ui线 程就是管理着用户界面的那个线程! android的ui线程操作并不是安全的,并且和用户直接进行界面交互的操作都必须在 ui线程中进行才可以.这种模式叫做单线程模式. 我们在单线程模式下编程一定要注意:不要阻塞ui线程.确保只在ui 线程中访问ui组件 当我们要执行一个复杂耗时的算法并且最终要将计算结果反映到ui上时,我们会发现,我们根本没办 法同时保证上面的两点要求:我们

Android AsyncTask异步处理

在开发Android应用时必须遵守单线程模型的原则: Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行. 在单线程模型中始终要记住两条法则: 1. 不要阻塞UI线程 2. 确保只在UI线程中访问Android UI工具包 当一个程序第 一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件 ,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理.所以主线程通常又被叫做UI

Android线程操作对象AsyncTask线程机制

 简单的说,一个程序只有一个主线程,可以有多个主线程.在Android世界中也是这样,Android属于单线程模型,耗时操作必须放在非主线程中执行,故而谷歌为了方便我们使用线程,为我们提供一个AsyncTask多线程操作对象.   对于Android使用线程还有一点需要特别注意,哪就是Android不允许在子线程中更新UI,相信很多初学者一定遇到过这个问题,这个怎么解决呢?在Activity中,我们可以通过   new Thread(new Runnable() { @Override publ

Android:多线程之AsyncTask

 AsyncTask AsyncTask,异步任务,可以简单进行异步操作,并把执行结果发布到UI主线程.AsyncTask是一个抽象类,它的内部其实也是结合了Thread和Handler来实现异步线程操作,但是它形成了一个通用线程框架,更清晰简单.AsyncTask应该被用于比较简短的操作(最多几秒钟).如果需要保持长时间运行的线程,可以使用ThreadPooExecutor或者FutureTask,关于这两个类的内容,以后再介绍,本片博客主要介绍AsyncTask. AsyncTask被定义为

解决如何让AsyncTask终止操作

 受到这个的启发终于结局了如何在AsyncTask运行中终止其操作. 单纯的onCancelled(true)是不行的 下面把代码贴出来~实现了登陆功能. AsyncTask简介,它使创建需要与用户界面交互的长时间运行的任务变得更简单.相对来说AsyncTask更轻量级一些,适用于简单的异步处理,不需要借助线程和Handler即可实现. package com.isummation.exampleapp; import java.io.BufferedReader; import java.io

Android 中文 API (101) —— AsyncTask

前言 本章内容是android.os.AsyncTask,版本为Android 2.3 r1,翻译来自"0_1",欢迎访问它的博客:"http://dev.10086.cn/blog/?32546",再次感谢"0_1" !期待你一起参与Android API的翻译,联系我over140@gmail.com.    声明 欢迎转载,但请保留文章原始出处:)  博客园:http://www.cnblogs.com/ Android中文翻译组:http

Android AsyncTask完全解析,带你从源码的角度彻底理解

我们都知道,Android UI是线程不安全的,如果想要在子线程里进行UI操作,就需要借助Android的异步消息处理机制.之前我也写过了一篇文章从源码层面分析了Android的异步消息处理机制,感兴趣的朋友可以参考 Android Handler.Message完全解析,带你从源码的角度彻底理解 . 不过为了更加方便我们在子线程中更新UI元素,Android从1.5版本就引入了一个AsyncTask类,使用它就可以非常灵活方便地从子线程切换到UI线程,我们本篇文章的主角也就正是它了. Asyn

android-在哪个线程中运行 AsyncTask?

问题描述 在哪个线程中运行 AsyncTask? 应用程序的 AlertDialog.Builder(context) 中有下面的代码.问题是在哪个线程中运行呢? final Thread myPrettyOperation = new Thread() { @Override public void run() { //Do some really long operation. } }; class MyPrettyTask extends AsyncTask<Void, Integer,