乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      教你寫Http框架(二)——三個(gè)例子帶你深入理解AsyncTask

       圖書館送餐人員 2016-03-16

      這個(gè)標(biāo)題大家不要奇怪,扯Http框架怎么扯到AsyncTask去了,有兩個(gè)原因:首先是Http框架除了核心http理論外,其技術(shù)實(shí)現(xiàn)核心也是線程池 模板 handler,而AsyncTask又正好也是這三者的完美結(jié)合。其次,也是自己在面試中發(fā)現(xiàn)大量的安卓開(kāi)發(fā)者完全不了解AsyncTask的原理和技術(shù)細(xì)節(jié),而AsyncTask的思想在我們?cè)O(shè)計(jì)app框架和性能調(diào)優(yōu)的時(shí)候是非常有用的。所以這里特地寫一篇關(guān)于AsyncTask的博文。
      老規(guī)矩,我的習(xí)慣還是通過(guò)寫demo,把核心技術(shù)一點(diǎn)點(diǎn)剝離出來(lái),一步步看完你就能深入理解其技術(shù)本質(zhì)了。

      第一個(gè)例子,先理解Java的線程池和FutureTask。先說(shuō)線程池,Java提供了一個(gè)非常重要的接口就是Executor。幾乎所有重要的線程池實(shí)現(xiàn)都繼承自這個(gè)接口,不過(guò)這個(gè)不是我們今天的重點(diǎn),具體請(qǐng)查看Java的API手冊(cè),我們上代碼看一下一般線程池是怎么實(shí)例化的。

      private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
      private static final int CORE_POOL_SIZE = CPU_COUNT   1;
      private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2   1;
      private static final int KEEP_ALIVE = 1;
      
      private static final BlockingQueue<Runnable> workQueue =
                  new LinkedBlockingQueue<Runnable>(10);
      private static final ThreadFactory threadFactory = new ThreadFactory()
      {
          private final AtomicInteger count = new AtomicInteger(1);
      
          @Override
          public Thread newThread(Runnable r)
          {
              return new Thread(r, 'AsyncTask #'   count.getAndIncrement());
          }
      };
      private static final ThreadPoolExecutor THREAD_POOL_EXECUTOR =
                  new ThreadPoolExecutor(
                          CORE_POOL_SIZE, 
                          MAXIMUM_POOL_SIZE, 
                          KEEP_ALIVE, 
                          TimeUnit.SECONDS, 
                          workQueue, 
                          threadFactory);
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25

      敏感的同學(xué)會(huì)發(fā)現(xiàn),這個(gè)就是AsyncTask的線程池的源碼,的確,正常的需求,這段代碼實(shí)例化出來(lái)的線程池基本都可以滿足了。其他參數(shù)看命名都很容易理解,這里主要講一下workQueue,因?yàn)槲覀儠?huì)不斷提交任務(wù)給線程池執(zhí)行,而線程池的線程數(shù)量是有限的,當(dāng)所有核心線程都處于工作狀態(tài)時(shí),client再次提交的任務(wù)放在哪里呢?我這么一問(wèn)你就懂了吧。
      再講一下java的FutureTask,我們知道正常情況下我們需要一個(gè)線程運(yùn)行,提交的是一個(gè)Runnable,但有時(shí)候我們希望線程運(yùn)行結(jié)束時(shí)帶回一個(gè)處理完成的數(shù)據(jù),這個(gè)時(shí)候Runnable就無(wú)力了,這個(gè)時(shí)候就要看FutureTask了。大家有興趣可以看一下它的源碼,其實(shí)它也是繼承自Runnable的,所以可以直接提交給線程來(lái)執(zhí)行。一般正常調(diào)用FutureTask的方法如下代碼:

      import java.util.concurrent.Callable;
      import java.util.concurrent.ExecutionException;
      import java.util.concurrent.Executor;
      import java.util.concurrent.Executors;
      import java.util.concurrent.FutureTask;
      
      public class Test1
      {
          public static void main(String[] args)
          {
              Test1 test = new Test1();
              test.test();
          }
      
          public void test()
          {
              FutureTask<String> fTask = new FutureTask<String>(new Callable<String>()
              {
                  @Override
                  public String call() throws Exception
                  {
                      System.out.println('calling');
                      return 'hello';
                  }
              })
              {
                  @Override
                  protected void done()
                  {
                      try
                      {
                          System.out.println('done '   get());
                      }
                      catch (InterruptedException e)
                      {
                          e.printStackTrace();
                      }
                      catch (ExecutionException e)
                      {
                          e.printStackTrace();
                      }
      
                      super.done();
                  }
              };
      
              Executor executor = Executors.newSingleThreadExecutor();
              executor.execute(fTask);
          }
      
      
      }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52

      以上代碼的運(yùn)行結(jié)果為:
      calling
      done hello
      所以,我們?cè)诰€程結(jié)束時(shí)拿到了最終的線程處理結(jié)果,而AsyncTask在onPostExecute中給你結(jié)果的時(shí)候,就是這么干的。

      第二個(gè)例子,我們來(lái)點(diǎn)干貨,我們先寫個(gè)AsyncTask的例子,跑起來(lái)并看下運(yùn)行結(jié)果,先代碼:

      package com.amuro.activity;
      
      import android.app.Activity;
      import android.os.AsyncTask;
      import android.os.Bundle;
      import android.util.Log;
      import android.view.View;
      
      import com.amuro.R;
      
      public class MainActivity extends Activity
      {
      
          @Override
          protected void onCreate(Bundle savedInstanceState)
          {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main_layout);
      
              findViewById(R.id.bt).setOnClickListener(new View.OnClickListener()
              {
                  @Override
                  public void onClick(View v)
                  {
                     testAsync();
                  }
      
              });
          }
      
          private void testAsync()
          {
              for(int i = 0; i < 10; i  )
              {
                  final int j = i;
                  AsyncTask<String, Integer, String> aTask =
                          new AsyncTask<String, Integer, String>()
                  {
                      @Override
                      protected void onProgressUpdate(Integer... values)
                      {
                          super.onProgressUpdate(values);
                      }
      
                      @Override
                      protected String doInBackground(String... params)
                      {
                          Log.e('amuro', Thread.currentThread().getName());
                          try
                          {
                              Thread.sleep(3000);
                          }
                          catch (InterruptedException e)
                          {
                              e.printStackTrace();
                          }
                          return params[0]   'done';
                      }
      
                      @Override
                      protected void onPostExecute(String s)
                      {
                          Log.e('amuro', 'result: '   s   ' '   j);
                      }
                  };
                  aTask.execute('DoubleX');
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70

      看下運(yùn)行結(jié)果:
      03-13 11:23:47.950 22777-23081/com.amuro E/amuro: AsyncTask #1
      03-13 11:23:50.955 22777-22777/com.amuro E/amuro: result: DoubleXdone 0
      03-13 11:23:50.955 22777-23120/com.amuro E/amuro: AsyncTask #2
      03-13 11:23:53.960 22777-22777/com.amuro E/amuro: result: DoubleXdone 1
      03-13 11:23:53.960 22777-23195/com.amuro E/amuro: AsyncTask #3
      03-13 11:23:56.965 22777-22777/com.amuro E/amuro: result: DoubleXdone 2
      03-13 11:23:56.965 22777-23236/com.amuro E/amuro: AsyncTask #4
      03-13 11:23:59.960 22777-22777/com.amuro E/amuro: result: DoubleXdone 3
      03-13 11:23:59.965 22777-23277/com.amuro E/amuro: AsyncTask #5
      03-13 11:24:02.965 22777-22777/com.amuro E/amuro: result: DoubleXdone 4
      03-13 11:24:02.965 22777-23277/com.amuro E/amuro: AsyncTask #5
      03-13 11:24:05.965 22777-22777/com.amuro E/amuro: result: DoubleXdone 5
      03-13 11:24:05.970 22777-23277/com.amuro E/amuro: AsyncTask #5
      03-13 11:24:08.975 22777-22777/com.amuro E/amuro: result: DoubleXdone 6
      03-13 11:24:08.975 22777-23277/com.amuro E/amuro: AsyncTask #5
      03-13 11:24:11.975 22777-22777/com.amuro E/amuro: result: DoubleXdone 7
      03-13 11:24:11.975 22777-23277/com.amuro E/amuro: AsyncTask #5
      03-13 11:24:14.980 22777-22777/com.amuro E/amuro: result: DoubleXdone 8
      03-13 11:24:14.980 22777-23081/com.amuro E/amuro: AsyncTask #1
      03-13 11:24:17.985 22777-22777/com.amuro E/amuro: result: DoubleXdone 9
      可以看到,10個(gè)任務(wù)是順序執(zhí)行的,并且只有5個(gè)線程在工作,好,
      我們把AsyncTask剛才那個(gè)線程池和FutureTask結(jié)合起來(lái),寫一個(gè)簡(jiǎn)單的例子實(shí)現(xiàn)和它一模一樣的功能。代碼:

      package com.amuro;
      
      import java.util.ArrayDeque;
      import java.util.ArrayList;
      import java.util.List;
      import java.util.concurrent.BlockingQueue;
      import java.util.concurrent.Callable;
      import java.util.concurrent.ExecutionException;
      import java.util.concurrent.Executor;
      import java.util.concurrent.FutureTask;
      import java.util.concurrent.LinkedBlockingQueue;
      import java.util.concurrent.ThreadFactory;
      import java.util.concurrent.ThreadPoolExecutor;
      import java.util.concurrent.TimeUnit;
      import java.util.concurrent.atomic.AtomicInteger;
      
      public class Test2
      {
      
          public static void main(String[] args)
          {
              Test2 test = new Test2();
              test.test();
          }
      
          private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
          private static final int CORE_POOL_SIZE = CPU_COUNT   1;
          private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2   1;
          private static final int KEEP_ALIVE = 1;
      
          private static final BlockingQueue<Runnable> workQueue =
                  new LinkedBlockingQueue<Runnable>(10);
          private static final ThreadFactory threadFactory = new ThreadFactory()
          {
              private final AtomicInteger count = new AtomicInteger(1);
      
              @Override
              public Thread newThread(Runnable r)
              {
                  return new Thread(r, 'AsyncTask #'   count.getAndIncrement());
              }
          };
          private static final ThreadPoolExecutor THREAD_POOL_EXECUTOR =
                  new ThreadPoolExecutor(
                          CORE_POOL_SIZE, 
                          MAXIMUM_POOL_SIZE, 
                          KEEP_ALIVE, 
                          TimeUnit.SECONDS, 
                          workQueue, 
                          threadFactory);
      
          private static volatile Executor defaultExecutor = new Executor()
          {
              final ArrayDeque<Runnable> tasks = new ArrayDeque<Runnable>();
              Runnable activeRunnable;
      
              @Override
              public void execute(final Runnable r)
              {
                  tasks.offer(new Runnable()
                  {
      
                      @Override
                      public void run()
                      {
                          try
                          {
                              System.out.println(Thread.currentThread().getName());
                              r.run();
                          }
                          finally
                          {
                              scheduleNext();
                          }
                      }
                  });
      
                  if(activeRunnable == null)
                  {
                      scheduleNext();
                  }
              }
      
              protected synchronized void scheduleNext()
              {
                  if((activeRunnable = tasks.poll()) != null)
                  {
                      THREAD_POOL_EXECUTOR.execute(activeRunnable);
                  }
              }
          };
      
          public void test()
          {
              List<FutureTask<String>> fList = new ArrayList<FutureTask<String>>();
              for(int i = 0; i < 10; i  )
              {
                  final int j = i;
      
                  fList.add(new FutureTask<String>(new Callable<String>()
                  {
      
                      @Override
                      public String call() throws Exception
                      {
                          Thread.sleep(3000);
                          return 'I'm callable '   j;
                      }
                  }){
                      @Override
                      protected void done()
                      {
                          try
                          {
                              System.out.println(get()   ' done');
                          }
                          catch (InterruptedException e)
                          {
                              e.printStackTrace();
                          }
                          catch (ExecutionException e)
                          {
                              e.printStackTrace();
                          }
                      }
                  }
      
                  );
              }
      
              for(FutureTask<String> fTask : fList)
              {
                  defaultExecutor.execute(fTask);
              }
          }
      
      }
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
      • 88
      • 89
      • 90
      • 91
      • 92
      • 93
      • 94
      • 95
      • 96
      • 97
      • 98
      • 99
      • 100
      • 101
      • 102
      • 103
      • 104
      • 105
      • 106
      • 107
      • 108
      • 109
      • 110
      • 111
      • 112
      • 113
      • 114
      • 115
      • 116
      • 117
      • 118
      • 119
      • 120
      • 121
      • 122
      • 123
      • 124
      • 125
      • 126
      • 127
      • 128
      • 129
      • 130
      • 131
      • 132
      • 133
      • 134
      • 135
      • 136
      • 137

      先看運(yùn)行結(jié)果:
      AsyncTask #1
      I’m callable 0 done
      AsyncTask #2
      I’m callable 1 done
      AsyncTask #3
      I’m callable 2 done
      AsyncTask #4
      I’m callable 3 done
      AsyncTask #5
      I’m callable 4 done
      AsyncTask #5
      I’m callable 5 done
      AsyncTask #5
      I’m callable 6 done
      AsyncTask #5
      I’m callable 7 done
      AsyncTask #5
      I’m callable 8 done
      AsyncTask #5
      I’m callable 9 done
      是不是一模一樣~沒(méi)錯(cuò)其實(shí)我們正常調(diào)用AsyncTask的execute方法的時(shí)候,就是調(diào)用了這個(gè)defaultExecutor,它的作用就是維持了一個(gè)雙向的任務(wù)隊(duì)列,當(dāng)AsyncTask的execute方法執(zhí)行的時(shí)候,它就把client提交的任務(wù)塞到了這個(gè)隊(duì)列里,如果這時(shí)候沒(méi)有任務(wù)在執(zhí)行,activeRunnable就為null,則scheduleNext方法直接調(diào)用,這個(gè)剛被提交的任務(wù)就會(huì)從隊(duì)列中被取出交給線程池區(qū)執(zhí)行,執(zhí)行完成后又會(huì)繼續(xù)調(diào)用scheduleNext方法,有任務(wù)就會(huì)繼續(xù)執(zhí)行下一個(gè)任務(wù)。所以你看到的結(jié)果就是這樣一個(gè)順序執(zhí)行,并且線程池只使用了5個(gè)線程,充分利用了資源。補(bǔ)充一點(diǎn),AsyncTask的源碼中,如果你想把所有任務(wù)改為并行執(zhí)行,是可以傳一個(gè)自己的Executor進(jìn)來(lái)的,但是這個(gè)方法被hide了,看來(lái)是官方不建議大家這么做。

      理解了上面兩個(gè)例子的話,第三個(gè)例子寫起來(lái)就so easy了,沒(méi)錯(cuò),理解輪子的最好試金石就是自己寫個(gè)輪子,所以下面我們就是要簡(jiǎn)單地寫一個(gè)自己的AsyncTask,和java直接run最大的區(qū)別就是安卓的非UI線程不能操作UI線程的實(shí)例,這個(gè)時(shí)候,把handler君請(qǐng)過(guò)來(lái)就好了嘛~ 還是先看代碼,我們自定義一個(gè)MyAsyncTask:

      package com.amuro.thread;
      
      import android.os.AsyncTask;
      import android.os.Handler;
      import android.os.Message;
      
      import java.util.ArrayDeque;
      import java.util.concurrent.BlockingQueue;
      import java.util.concurrent.Callable;
      import java.util.concurrent.Executor;
      import java.util.concurrent.FutureTask;
      import java.util.concurrent.LinkedBlockingQueue;
      import java.util.concurrent.ThreadFactory;
      import java.util.concurrent.ThreadPoolExecutor;
      import java.util.concurrent.TimeUnit;
      import java.util.concurrent.atomic.AtomicInteger;
      import java.util.logging.LogRecord;
      
      /**
       * Created by Echo on 2016/3/12.
       */
      public abstract class MyAsyncTask<Params, Result>
      {
          /*************線程池核心代碼*******************/
          private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
          private static final int CORE_POOL_SIZE = CPU_COUNT   1;
          private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2   1;
          private static final int KEEP_ALIVE = 1;
      
          private static final BlockingQueue<Runnable> workQueue =
                  new LinkedBlockingQueue<Runnable>(10);
          private static final ThreadFactory threadFactory = new ThreadFactory()
          {
              private final AtomicInteger count = new AtomicInteger(1);
      
              @Override
              public Thread newThread(Runnable r)
              {
                  return new Thread(r, 'MyAsyncTask #'   count.getAndIncrement());
              }
          };
          private static final ThreadPoolExecutor THREAD_POOL_EXECUTOR =
                  new ThreadPoolExecutor(
                          CORE_POOL_SIZE,
                          MAXIMUM_POOL_SIZE,
                          KEEP_ALIVE,
                          TimeUnit.SECONDS,
                          workQueue,
                          threadFactory);
      
          private static volatile Executor defaultExecutor = new Executor()
          {
              final ArrayDeque<Runnable> tasks = new ArrayDeque<Runnable>();
              Runnable activeRunnable;
      
              @Override
              public void execute(final Runnable r)
              {
                  tasks.offer(new Runnable()
                  {
      
                      @Override
                      public void run()
                      {
                          try
                          {
                              r.run();
                          }
                          finally
                          {
                              scheduleNext();
                          }
                      }
                  });
      
                  if(activeRunnable == null)
                  {
                      scheduleNext();
                  }
              }
      
              protected synchronized void scheduleNext()
              {
                  if((activeRunnable = tasks.poll()) != null)
                  {
                      THREAD_POOL_EXECUTOR.execute(activeRunnable);
                  }
              }
          };
      
          /****************消息處理核心代碼************************/
          private static final int MESSAGE_POST_RESULT = 0x01;
      
          private static class AsyncTaskResult<Data>
          {
              final MyAsyncTask mTask;
              final Data[] mData;
      
              AsyncTaskResult(MyAsyncTask task, Data... data)
              {
                  mTask = task;
                  mData = data;
              }
          }
      
          private static abstract class WorkerRunnable<Params, Result>
                  implements Callable<Result> {
              Params[] mParams;
          }
      
          private static final Handler handler = new Handler()
          {
              @Override
              public void handleMessage(Message msg)
              {
                  AsyncTaskResult result = (AsyncTaskResult) msg.obj;
                  switch (msg.what)
                  {
                      case MESSAGE_POST_RESULT:
                          result.mTask.finish(result.mData[0]);
                          break;
                  }
              }
          };
          private final WorkerRunnable<Params, Result> workerRunnable;
          private final FutureTask<Result> futureTask;
      
          public MyAsyncTask()
          {
              workerRunnable = new WorkerRunnable<Params, Result>()
              {
                  @Override
                  public Result call() throws Exception
                  {
                      return postResult(doInBackground(mParams));
                  }
              };
      
              futureTask = new FutureTask<Result>(workerRunnable);
          }
      
          private Result postResult(Result result)
          {
              Message message = handler.obtainMessage(
                      MESSAGE_POST_RESULT,
                      new AsyncTaskResult<Result>(this, result));
              message.sendToTarget();
              return result;
          }
      
          private void finish(Result result)
          {
              onPostExecute(result);
          }
      
          protected void onPreExecute(){}
      
          protected abstract Result doInBackground(Params... params);
      
          protected void onPostExecute(Result result){}
      
          public final MyAsyncTask<Params, Result> execute(Params... params)
          {
              return executeOnExecutor(defaultExecutor, params);
          }
      
          public final MyAsyncTask<Params, Result> executeOnExecutor(Executor executor, Params... params)
          {
              onPreExecute();
      
              workerRunnable.mParams = params;
              executor.execute(futureTask);
              return this;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
      • 88
      • 89
      • 90
      • 91
      • 92
      • 93
      • 94
      • 95
      • 96
      • 97
      • 98
      • 99
      • 100
      • 101
      • 102
      • 103
      • 104
      • 105
      • 106
      • 107
      • 108
      • 109
      • 110
      • 111
      • 112
      • 113
      • 114
      • 115
      • 116
      • 117
      • 118
      • 119
      • 120
      • 121
      • 122
      • 123
      • 124
      • 125
      • 126
      • 127
      • 128
      • 129
      • 130
      • 131
      • 132
      • 133
      • 134
      • 135
      • 136
      • 137
      • 138
      • 139
      • 140
      • 141
      • 142
      • 143
      • 144
      • 145
      • 146
      • 147
      • 148
      • 149
      • 150
      • 151
      • 152
      • 153
      • 154
      • 155
      • 156
      • 157
      • 158
      • 159
      • 160
      • 161
      • 162
      • 163
      • 164
      • 165
      • 166
      • 167
      • 168
      • 169
      • 170
      • 171
      • 172
      • 173
      • 174
      • 175
      • 176

      然后再看一下調(diào)用的代碼:

      package com.amuro.activity;
      
      import android.app.Activity;
      import android.os.AsyncTask;
      import android.os.Bundle;
      import android.util.Log;
      import android.view.View;
      
      import com.amuro.R;
      import com.amuro.thread.MyAsyncTask;
      
      public class MainActivity extends Activity
      {
      
          @Override
          protected void onCreate(Bundle savedInstanceState)
          {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main_layout);
      
              findViewById(R.id.bt).setOnClickListener(new View.OnClickListener()
              {
                  @Override
                  public void onClick(View v)
                  {
                     testAsync();
                  }
      
              });
      
              findViewById(R.id.bt1).setOnClickListener(new View.OnClickListener()
              {
                  @Override
                  public void onClick(View v)
                  {
                      testMyAsync();
                  }
              });
          }
      
          private void testAsync()
          {
              for(int i = 0; i < 10; i  )
              {
                  final int j = i;
                  AsyncTask<String, Integer, String> aTask =
                          new AsyncTask<String, Integer, String>()
                  {
                      @Override
                      protected void onProgressUpdate(Integer... values)
                      {
                          super.onProgressUpdate(values);
                      }
      
                      @Override
                      protected String doInBackground(String... params)
                      {
                          Log.e('amuro', Thread.currentThread().getName());
                          try
                          {
                              Thread.sleep(1000);
                          }
                          catch (InterruptedException e)
                          {
                              e.printStackTrace();
                          }
                          return params[0]   'done';
                      }
      
                      @Override
                      protected void onPostExecute(String s)
                      {
                          Log.e('amuro', 'result: '   s   ' '   j);
                      }
                  };
                  aTask.execute('DoubleX');
              }
          }
      
          private void testMyAsync()
          {
              for(int i = 0; i < 10; i  )
              {
                  final int j = i;
      
                  MyAsyncTask<String, String> myTask = new MyAsyncTask<String, String>()
                  {
                      @Override
                      protected String doInBackground(String... params)
                      {
                          Log.e('amuro', Thread.currentThread().getName());
                          try
                          {
                              Thread.sleep(1000);
                          }
                          catch (InterruptedException e)
                          {
                              e.printStackTrace();
                          }
                          return params[0]   'done';
                      }
      
                      @Override
                      protected void onPostExecute(String s)
                      {
                          Log.e('amuro', 'result: '   s   ' '   j);
                      }
                  };
                  myTask.execute('outSideParam ');
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
      • 88
      • 89
      • 90
      • 91
      • 92
      • 93
      • 94
      • 95
      • 96
      • 97
      • 98
      • 99
      • 100
      • 101
      • 102
      • 103
      • 104
      • 105
      • 106
      • 107
      • 108
      • 109
      • 110
      • 111
      • 112
      • 113

      再看一下運(yùn)行結(jié)果:
      03-13 13:15:55.065 20514-20732/com.amuro E/amuro: MyAsyncTask #1
      03-13 13:15:56.070 20514-20514/com.amuro E/amuro: result: outSideParam done 0
      03-13 13:15:56.070 20514-20747/com.amuro E/amuro: MyAsyncTask #2
      03-13 13:15:57.075 20514-20514/com.amuro E/amuro: result: outSideParam done 1
      03-13 13:15:57.075 20514-20758/com.amuro E/amuro: MyAsyncTask #3
      03-13 13:15:58.075 20514-20514/com.amuro E/amuro: result: outSideParam done 2
      03-13 13:15:58.075 20514-20758/com.amuro E/amuro: MyAsyncTask #3
      03-13 13:15:59.075 20514-20514/com.amuro E/amuro: result: outSideParam done 3
      03-13 13:15:59.075 20514-20758/com.amuro E/amuro: MyAsyncTask #3
      03-13 13:16:00.080 20514-20514/com.amuro E/amuro: result: outSideParam done 4
      03-13 13:16:00.080 20514-20758/com.amuro E/amuro: MyAsyncTask #3
      03-13 13:16:01.080 20514-20514/com.amuro E/amuro: result: outSideParam done 5
      03-13 13:16:01.080 20514-20758/com.amuro E/amuro: MyAsyncTask #3
      03-13 13:16:02.080 20514-20514/com.amuro E/amuro: result: outSideParam done 6
      03-13 13:16:02.080 20514-20758/com.amuro E/amuro: MyAsyncTask #3
      03-13 13:16:03.085 20514-20514/com.amuro E/amuro: result: outSideParam done 7
      03-13 13:16:03.085 20514-20758/com.amuro E/amuro: MyAsyncTask #3
      03-13 13:16:04.085 20514-20514/com.amuro E/amuro: result: outSideParam done 8
      03-13 13:16:04.090 20514-20732/com.amuro E/amuro: MyAsyncTask #1
      03-13 13:16:05.095 20514-20514/com.amuro E/amuro: result: outSideParam done 9
      暴露了我的測(cè)試機(jī)弱爆了,Orz。
      為了簡(jiǎn)單起見(jiàn)這里就不處理onProgressUpdate了,有興趣的同學(xué)可以在這個(gè)基礎(chǔ)上自己去實(shí)現(xiàn)。我在這里總結(jié)一下execute方法執(zhí)行的整個(gè)流程。
      1. 先回調(diào)了onPreExecute方法,這個(gè)是在UI線程里的。然后把外面?zhèn)魅氲膒arams賦值給了workerRunnable,其實(shí)就是FutureTask需要的Callable對(duì)象。
      2. 然后就把這個(gè)FutureTask丟給了我們的defaultExecutor去執(zhí)行,這個(gè)流程和上面的例子二是一樣一樣的。
      3. 執(zhí)行成功后子線程完成了結(jié)果的生成,這個(gè)時(shí)候就可以通過(guò)handler把結(jié)果丟給UI線程了。這里封裝了一個(gè)AsyncTaskResult類來(lái)傳遞結(jié)果,原因很簡(jiǎn)單,handler是靜態(tài)對(duì)象,沒(méi)法直接拿到當(dāng)前MyAsyncTask的引用。而我們要把task和result對(duì)象同時(shí)丟給handler,所以要進(jìn)行一下封裝。
      4. OK,handler拿到result之后就會(huì)把task拿出來(lái)并回調(diào)finish方法。
      5. finish方法,這個(gè)時(shí)候已經(jīng)在UI線程中了,所以可以回調(diào)最終的onPostExecute方法把結(jié)果丟給client去處理了。

      無(wú)論多么復(fù)雜的技術(shù)或?qū)崿F(xiàn),只要我們抓到其本質(zhì),耐心地把它涉及到的知識(shí)一點(diǎn)點(diǎn)的吃透,并多寫代碼多做測(cè)試。最終你會(huì)發(fā)現(xiàn),再?gòu)?fù)雜,不過(guò)也是小知識(shí)的層疊和擴(kuò)展罷了。這和一個(gè)互聯(lián)網(wǎng)公司需要深厚的技術(shù)積累,道理也是一樣的。

      就醬,謝謝觀賞~

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多