AsyncTask与FutureTask运用介绍

来源:互联网 发布:网络大学 编辑:程序博客网 时间:2024/06/09 22:59

AsyncTask类:

  • 官方英文介绍:

    AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers .

    AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask .

    An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.

  • 中文介绍

    • AsyncTask能够正确和容易使用在UI线程中。

    • AsynTask这个类提供在单个后台线程中执行的方法,且将执行结果回调到主线程,重要的是不需要你手动配置多线程或者Handler来实现

    • AsynTask的设计成一个(围绕thread和Handler)帮助类,并不构成通用线程框架。

    • AsynTask适合使用在短期操作(至多几分钟)

    • AsynTask不适合长期操作,进行长期操作,应该使用 java.util.concurrent 包下的Executor,ThreadPoolExecutor 和FutureTask.

    • AsynTask的创建通过3个泛型类型,参数类型,进度类型,结果类型

  • 其API

    • onPreExecute():在doInBackground()前执行,通常用于显示Progress bar

    • doInBackground() :运行在工作线程中,执行耗时操作.
      调用publishProgress()传递进度,onProgressUpdate()上回接受到进度,从而更新UI

    • onProgressUpdate():接受publishProgress()传递过来的任务精度,从而更新ui,通常在textview上显示进度,或者在Progress bar上更新进度

    • onPostExecute(): 当doInBackgroud()方法执行完后,会传递结果到主线程中,进行UI操作

    • cancel(boolean mayInterruptIfRunning):取消任务

    • execute(Params… params):给定参数,执行任务

    • execute(Runnable runnable):在线程池中执行一个异步Runnable任务,不会回调到主线程中。

    • executeOnExecutor(Executor exec, Params… params):给定参数,线程池,并发执行任务

    • get(long timeout, TimeUnit unit):指定任务执行时间,然后返回执行结果

    • get():返回执行完的结果

    • getStatus():返回当前任务的状态

    • isCancelled():检查当前任务是否被取消,若是取消,返回true

    • AsyncTask类的api: https://developer.android.com/reference/android/os/AsyncTask.html

  • 注意的细节

    1. AsyncTask’s generic types(泛型类型)

      AsyncTask<Params, Progress, Result> 类型说明:  1.  Params是doInBackground()中参数类型  2.  Progress是onProgressUpdate()中参数类型  3.  Result是onPostExecute()中参数类型 
    2. Cancelling a task(取消任务)

        调用cancle()可以取消该任务。调用cancel()后,isCancelled() 会返回 true.   故调用cancle()前先调用 isCancelled()进行检查 注意点:当创建AsyncTask对象的activity销毁时,销毁该AsyncTask,防止持有activity的指针,防止内存溢出
    3. Threading rules(线程规则)

      1. AsyncTask 这个类必须创建在主线程中2. AsyncTask 对象必须创建在主线程中3. execute(Params...) 必须调用在主线程中4.  不能直接通过AsyncTask对象直接调用onPreExecute(), onPostExecute(Result),    doInBackground(Params...), onProgressUpdate(Progress...) 5.  AsyncTask对象只能执行一次(多次执行同一AsyncTask对象会报异常)
    4. Memory observability(内存观察)

      AsyncTask确保全部回调都是一种同步安全的方式调用
  • AsyncTask版本变化

    在DONUT(Android 1.6)之前,AsyncTask是执行在单后台线程

    在DONUT(Android 1.6)之后,AsyncTask改变为在线程池中多线程执行

    在HONEYCOMB(Android 3.0)之后:AsyncTask执行在单个线程中,避免并发执行导致的常见错误

    注意点: 在3.0 之后,若是要执行多线程并发操作,需要调用 executeOnExecutor(java.util.concurrent.Executor, Object[]) 和THREAD_POOL_EXECUTOR(用于并行执行任务程序).

  • AsyncTask使用案例

    1. 简单案例:

      private 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");   }}
      • 开启方式
        new DownloadFilesTask().execute(url1, url2, url3);
    2. 联网操作的案例:https://developer.android.com/training/basics/network-ops/connecting.html#download

        private class DownloadWebpageTask extends AsyncTask<String, Void, String> {    @Override    protected String doInBackground(String... urls) {        // params comes from the execute() call: params[0] is the url.        try {            return downloadUrl(urls[0]);        } catch (IOException e) {            return "Unable to retrieve web page. URL may be invalid.";        }    }    // onPostExecute displays the results of the AsyncTask.    @Override    protected void onPostExecute(String result) {        textView.setText(result);   }}private String downloadUrl(String myurl) throws IOException {    InputStream is = null;      // Only display the first 500 characters of the retrieved      // web page content.      int len = 500;    try {        URL url = new URL(myurl);        HttpURLConnection conn = (HttpURLConnection) url.openConnection();        conn.setReadTimeout(10000 /* milliseconds */);        conn.setConnectTimeout(15000 /* milliseconds */);        conn.setRequestMethod("GET");        conn.setDoInput(true);        // Starts the query        conn.connect();        int response = conn.getResponseCode();        Log.d(DEBUG_TAG, "The response is: " + response);       is = conn.getInputStream();       // Convert the InputStream into a string        String contentAsString = readIt(is, len);         return contentAsString;// Makes sure that the InputStream is closed after the app is// finished using it.     } finally {       if (is != null) {          is.close();       }   }}
    3. 进行图片处理的案例(经典案例):
      http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html


FutureTask类:

ps:分析AsyncTask的源码会用到FutureTask,在源码中FetureTask充当Runnable的角色,执行异步操作的功能。

FutureTask是实现Feture接口,创建其对象时要用到Callable,故先介绍Feture 接口,Callable接口。

  • Future接口:

    • 描述:

      1. 一个Futrue表示异步计算的结果。 2. 这个类提供 检查任务是否完成的方法,等待任务完成后返回检索出的结果的方法。 3. 调用get()获取结果,若是任务完成了,返回结果。反之,阻塞,直到任务完成后返回结果。4. 调用cancel()可以取消任务,前提是任务还没有完成,若是任务完成后,则不能被取消。5. 使用一个可以取消且不提供结果的Future,需声明 Future<?>这种形式,return null作为任务结果。
    • 其API:

      1.cancel(boolean mayInterruptIfRunning):取消正在执行的任务。(一旦任务完成,是不能被取消的)2.get(long timeout, TimeUnit unit):等待给定的时间进行任务,若是可用,检索其任务执行后的结果3.get():等待任务执行完,然后检索结果4.isCancelled():检查任务状态。在任务完成前,可以取消返回true5.isDone():任务完成,返回true
    • 使用案例:

      interface ArchiveSearcher {     String search(String target); }class App {       ExecutorService executor = ...      ArchiveSearcher searcher = ...     void showSearch(final String target)                  throws InterruptedException {          Future<String> future             = executor.submit(new Callable<String>() {                    public String call() {              return searcher.search(target);          }});        displayOtherThings(); // do other things while searching       try {            displayText(future.get()); // use future       } catch (ExecutionException ex) { cleanup(); return; }}}
    • Memory consistency effects(内存一致性):
      在异步线程中执行计算操作,是发生在其他线程中调用Future.get() 之前。

  • Callable接口:

    • 描述: 一个返回结果且可能抛出异常的任务
    • api : V call():返回结果
  • FutureTask类:
    FutureTask实现Future,Runnable类,通常被Executor执行。

    // 替换Future案例中的submit功能代码: FutureTask<String> future =     new FutureTask<>(new Callable<String>() {        public String call() {        return searcher.search(target); }}); executor.execute(future);
    • 描述:

      • 一个可以取消的异步计算。这个类提供Future的基本实现。包含开始和取消一个任务的方法,查询任务进度及返回任务结果的方法。
      • 一旦任务完成,不能重新启动任务,或者取消任务,除非使用runAndReset()方法后。

      • FutureTask可用于包装一个Callable或者Runnable对象。因为FutureTask实现了Runnable对象,所以FutureTask可以通过Executor的submitted执行

      • 除了作为独立类,这类还提供了受保护的功能,在 创建自定义任务时可能被用到

    • 其API(除开Future中继承的,特有的):

      • done(): 任务完成或者任务取消时,调用,任务状态变为isDone

      • runAndReset():执行一个不设置结果的任务,且重置初始状态。如果任务遇到异常或者被取消,这方法是不能执行的。

      • set(V v):设置Future中结果,在Future没有设置结果或者被取消的前提下。

FetureTask类的接:https://developer.android.com/reference/java/util/concurrent/FutureTask.html

想了解线程池知识点,可以查看 Android Thread Pool(线程池)

ps: 先了解类的Api,分析源码更容易, AsyncTask源码分析篇。

0 0
原创粉丝点击