Android AsyncTask

会有一股神秘感。 提交于 2019-12-01 21:57:50

简介:

    AsyncTask是android提供的轻量级的异步类。比Handler更轻量级一些,适用于简单的异步处理。

    AsyncTask内部封装了Thread和Handler,简化Thread+Handler,可以让我们在后台进行计算并且把计算的结果及时更新到UI上。

    AsyncTask并不是像多个线程那样完全并行执行的。

优缺点:

     优点:

         简单,快捷

         过程可控

         结构清晰,功能定义明确

         对于多个后台任务时,简单,清晰

     缺点:

         在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.

         在单个后台异步处理时,显得代码过多,结构过于复杂(相对性)

         AsyncTask中维护着一个长度为128的线程池,同时可以执行5个工作线程,还有一个缓冲队列,当线程池中已有128个线程,缓冲队列已满时,如果此时向线程提交任务,将会抛出RejectedExecutionException。

         解决:由一个控制线程来处理AsyncTask的调用判断线程池是否满了,如果满了则线程睡眠否则请求AsyncTask继续处理。

 

构造方法:

    AsyncTask直接继承于Object类,位置为android.os.AsyncTask。要使用AsyncTask工作我们要提供三个泛型参数,并重载几个方法(至少重载一个)。

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

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

     Progress 后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位。

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

一个异步加载数据最少要重写以下这两个方法:

    doInBackground(Params…) 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。

    onPostExecute(Result)  相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回

有必要的话你还得重写以下这三个方法,但不是必须的:

     onProgressUpdate(Progress…)   可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。当在后台任务中调用了publishProgress(Progress...)方法后,这个方法就很快会被调用,方法中携带的参数就是在后台任务中传递过来的。

     onPreExecute()     这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。

     onCancelled()       用户调用取消时,要做的操作

 

使用AsyncTask类,以下是几条必须遵守的准则:

     AsyncTask的类必须在UI线程加载(从4.1开始系统会帮我们自动完成)

     AsyncTask对象必须在UI线程创建

     execute方法必须在UI线程调用

     不要在你的程序中去直接调用onPreExecute(), onPostExecute, doInBackground, onProgressUpdate方法

     一个AsyncTask对象只能执行一次,即只能调用一次execute方法,否则会报运行时异常

    AsyncTask不是被设计为处理耗时操作的,耗时上限为几秒钟,如果要做长耗时操作,强烈建议你使用Executor,ThreadPoolExecutor以及FutureTask

    在1.6之前,AsyncTask是串行执行任务的,1.6的时候AsyncTask开始采用线程池里处理并行任务,但是从3.0开始,为了避免AsyncTask所带来的并发错误,AsyncTask又采用一个线程来串行执行任务

 

简单实例:

public class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
    protected Long doInBackground(URL... urls) {
        int count = urls.length;
        long totalSize = 0;
        for (int i = 0; i < count; i++) {
            totalSize += Downloader.downloadFile(urls[i]);
            publishProgress((int) ((i / (float) count) * 100));
            // Escape early if cancel() is called  
            if (isCancelled()) break;
        }
        return totalSize;
    }
    protected void onProgressUpdate(Integer... progress) {
        setProgressPercent(progress[0]);
    }
    protected void onPostExecute(Long result) {
        showDialog("Downloaded " + result + " bytes");
    }
}

 

AsyncTask在3.0以上的系统中并行起来

    AsyncTask在4.1.1及是串行的,在2.3.3应该是并行的

@TargetApi(Build.VERSION_CODES.HONEYCOMB)  
@Override  
public void onClick(View v) {  
    if (v == mButton) {  
        new MyAsyncTask("AsyncTask#1").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"");  
        new MyAsyncTask("AsyncTask#2").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"");  
        new MyAsyncTask("AsyncTask#3").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"");  
        new MyAsyncTask("AsyncTask#4").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"");  
        new MyAsyncTask("AsyncTask#5").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"");  
    }  
  
}  
  
private static class MyAsyncTask extends AsyncTask<String, Integer, String> {  
  
    private String mName = "AsyncTask";  
  
    public MyAsyncTask(String name) {  
        super();  
        mName = name;  
    }  
  
    @Override  
    protected String doInBackground(String... params) {  
        try {  
            Thread.sleep(3000);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        return mName;  
    }  
  
    @Override  
    protected void onPostExecute(String result) {  
        super.onPostExecute(result);  
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
        Log.e(TAG, result + "execute finish at " + df.format(new Date()));  
    }  
}

避免AsyncTask内存泄漏的简单例子

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!