天天看点

AsyncTask的使用及注意事项

一、什么是AsyncTask

AsyncTask(抽象类)其实就是安卓提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.

AsyncTask本质上封装了线程池和Handler的异步框架,用来执行异步任务的,让你避免使用线程类Thread

二、AsyncTask的使用方法

AsyncTask定义了三种泛型类型 Params,Progress和Result。

Params 启动任务执行的输入参数,比如HTTP请求的URL。

Progress 后台任务执行的百分比。

Result 后台执行任务最终返回的结果,比如String。

/**  
 * 生成该类的对象,并调用execute方法之后  
 * 首先执行的是onProExecute方法  
 * 其次执行doInBackgroup方法  
 *  
 */  
public class ProgressBarAsyncTask extends AsyncTask<Integer, Integer, String> {  

    private TextView textView;  
    private ProgressBar progressBar;  

    public ProgressBarAsyncTask(TextView textView, ProgressBar progressBar) {  
        super();  
        this.textView = textView;  
        this.progressBar = progressBar;  
    }  


    /**  
     * 这里的Integer参数对应AsyncTask中的第一个参数   
     * 这里的String返回值对应AsyncTask的第三个参数  
     * 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改  
     * 但是可以调用publishProgress方法触发onProgressUpdate对UI进行操作  
     */  
    @Override  
    protected String doInBackground(Integer... params) {  
        NetOperator netOperator = new NetOperator();  
        int i = ;  
        for (i = ; i <= ; i+=) {  
            netOperator.operator();  
            publishProgress(i);  
        }  
        return i + params[].intValue() + "";  
    }  


    /**  
     * 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值)  
     * 在doInBackground方法执行结束之后在运行,并且运行在UI线程当中 可以对UI空间进行设置  
     */  
    @Override  
    protected void onPostExecute(String result) {  
        textView.setText("异步操作执行结束" + result);  
    }  

    //该方法运行在UI线程当中,并且运行在UI线程当中 可以对UI空间进行设置  
    @Override  
    protected void onPreExecute() {  
        textView.setText("开始执行异步线程");  
    }  

    /**  
     * 这里的Intege参数对应AsyncTask中的第二个参数  
     * 在doInBackground方法当中,,每次调用publishProgress方法都会触发onProgressUpdate执行  
     * onProgressUpdate是在UI线程中执行,所有可以对UI空间进行操作  
     */  
    @Override  
    protected void onProgressUpdate(Integer... values) {  
        int vlaue = values[];  
        progressBar.setProgress(vlaue);  
    }    
}  
           

三、AsyncTask的内部原理

1、AsyncTask本质上是一个静态的线程池,AsyncTask实现的子类可以执行不同的异步任务,这些任务都是提交到线程池中进行执行。

2、线程池中的工作线程执行doInBackground()方法执行异步任务

3、当任务状态改变之后,工作线程会通过Handler向UI线程发送消息。

四、AsyncTask的注意事项

1、内存泄漏

一般情况下AsyncTask会被声明为Activity的非静态内部类,所以AsyncTask会持有外部类Activity的引用,这时候Activity被销毁了,而AsyncTask内部还在执行耗时操作,就导致了Activity无法被内存回收。

2、生命周期、结果丢失

AsyncTask并不会随着Activity的销毁而销毁,由于AsyncTask内部正在执行耗时操作,如果没有手动将AsyncTask实例cancel掉,他是不会随着Activity的销毁而销毁。基于这种情况,当Activity销毁了(屏幕旋转),而AsyncTask还在执行耗时操作,当执行完成时要刷新UI,此时Activity已经不存在了,从而导致崩溃,所以必须在onDestory()方法中调用cancel()方法销毁AsyncTask.

3、并行or串行

AsyncTask默认时串行执行的,如果想要并行执行则可以调用AsyncTask的executeOnExecutor,把自己的MyThreadPoolExecutor对象传进去

继续阅读