<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      奔跑的肥豬

      導(dǎo)航

      AsyncTask 進(jìn)行耗時(shí)操作和UI 更新

      相信各位對(duì) AsyncTask 不會(huì)陌生,雖然它有如下弊端:

      1. 如果在activiy內(nèi)部new 一個(gè)AsyncTask, 橫豎屏切換生成一個(gè)新的activity,等結(jié)果返回時(shí),處理不好容易出現(xiàn)NPE。

      2. 容易出現(xiàn)內(nèi)存泄漏,如果AsyncTask 進(jìn)行比較耗時(shí)的IO操作(網(wǎng)絡(luò)操作, 打開一個(gè)文件等等),在activity onDestroy的時(shí)候沒(méi)有cancel的話,

      導(dǎo)致該Activity不能被GC回收(AsyncTask 在Activity內(nèi)部執(zhí)行耗時(shí)操作)。

      3. 如果調(diào)用 executeOnExecutor, 如果等待queue里面的請(qǐng)求過(guò)多沒(méi)有得到及時(shí)處理,容易造成RejectException, 具體原因我在我的博客已經(jīng)有所介紹(AsyncTask RejectedExecutionException 小結(jié))。

      閑話少說(shuō), 本文的重點(diǎn)不在于介紹AsyncTask的優(yōu)缺點(diǎn),而是一直有一個(gè)問(wèn)題困擾我,為什么AsyncTask 里面既能進(jìn)行UI 操作,又能進(jìn)行耗時(shí)的操作。

      讓我們從代碼角度來(lái)分析這個(gè)問(wèn)題, 首先看他的構(gòu)造函數(shù):

      public AsyncTask() {
              mWorker = new WorkerRunnable<Params, Result>() {
                  public Result call() throws Exception {
                      mTaskInvoked.set(true);
                      Result result = null;
                      try {
                          Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                          //noinspection unchecked
                          result = doInBackground(mParams);
                          Binder.flushPendingCommands();
                      } catch (Throwable tr) {
                          mCancelled.set(true);
                          throw tr;
                      } finally {
                          postResult(result);
                      }
                      return result;
                  }
              };
      
              mFuture = new FutureTask<Result>(mWorker) {
                  @Override
                  protected void done() {
                      try {
                          postResultIfNotInvoked(get());
                      } catch (InterruptedException e) {
                          android.util.Log.w(LOG_TAG, e);
                      } catch (ExecutionException e) {
                          throw new RuntimeException("An error occurred while executing doInBackground()",
                                  e.getCause());
                      } catch (CancellationException e) {
                          postResultIfNotInvoked(null);
                      }
                  }
              };
          }
      private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
              Params[] mParams;
          }
      public class FutureTask<V> implements RunnableFuture<V>
      public interface Callable<V> {
          /**
           * Computes a result, or throws an exception if unable to do so.
           *
           * @return computed result
           * @throws Exception if unable to compute a result
           */
          V call() throws Exception;
      }

       

      public interface RunnableFuture<V> extends Runnable, Future<V> {
          /**
           * Sets this Future to the result of its computation
           * unless it has been cancelled.
           */
          void run();
      }

       

      從上面的代碼可以看出, mWorker 實(shí)際上就是一個(gè)  Callable, 而 mFuture 就是一個(gè)Thread, 構(gòu)造函數(shù)中將Callable 作為參數(shù)傳給了 FutureTask,下面

      我們看看FutureTask 中的相關(guān)實(shí)現(xiàn):

      public void run() {
              if (state != NEW ||
                  !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))
                  return;
              try {
                  Callable<V> c = callable;
                  if (c != null && state == NEW) {
                      V result;
                      boolean ran;
                      try {
                          result = c.call();
                          ran = true;
                      } catch (Throwable ex) {
                          result = null;
                          ran = false;
                          setException(ex);
                      }
                      if (ran)
                          set(result);
                  }
              } finally {
                  // runner must be non-null until state is settled to
                  // prevent concurrent calls to run()
                  runner = null;
                  // state must be re-read after nulling runner to prevent
                  // leaked interrupts
                  int s = state;
                  if (s >= INTERRUPTING)
                      handlePossibleCancellationInterrupt(s);
              }
          }
       protected void set(V v) {
              if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) {
                  outcome = v;
                  U.putOrderedInt(this, STATE, NORMAL); // final state
                  finishCompletion();
              }
          }
      private void finishCompletion() {
              // assert state > COMPLETING;
              for (WaitNode q; (q = waiters) != null;) {
                  if (U.compareAndSwapObject(this, WAITERS, q, null)) {
                      for (;;) {
                          Thread t = q.thread;
                          if (t != null) {
                              q.thread = null;
                              LockSupport.unpark(t);
                          }
                          WaitNode next = q.next;
                          if (next == null)
                              break;
                          q.next = null; // unlink to help gc
                          q = next;
                      }
                      break;
                  }
              }
      
              done();
      
              callable = null;        // to reduce footprint
          }

       

      可以看到 result = c.call(); 在run方法中被調(diào)用, 實(shí)際就是 result = doInBackground(mParams); 被調(diào)用,因?yàn)樵摲椒ㄊ窃谧泳€程里面執(zhí)行,所以可以執(zhí)行耗時(shí)操作。 繼續(xù)讀代碼,call-> set(result) -> finishCompletion->done()-> postResultIfNotInvoked-> postResult

       private Result postResult(Result result) {
              @SuppressWarnings("unchecked")
              Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                      new AsyncTaskResult<Result>(this, result));
              message.sendToTarget();
              return result;
          }
      private static Handler getHandler() {
              synchronized (AsyncTask.class) {
                  if (sHandler == null) {
                      sHandler = new InternalHandler();
                  }
                  return sHandler;
              }
          }
       private static class InternalHandler extends Handler {
              public InternalHandler() {
                  super(Looper.getMainLooper());
              }
      
              @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
              @Override
              public void handleMessage(Message msg) {
                  AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
                  switch (msg.wh所以at) {
                      case MESSAGE_POST_RESULT:
                          // There is only one result
                          result.mTask.finish(result.mData[0]);
                          break;
                      case MESSAGE_POST_PROGRESS:
                          result.mTask.onProgressUpdate(result.mData);
                          break;
                  }
              }
          }

      相信上面的代碼大家都能看懂,值得說(shuō)明的是,因?yàn)?nbsp;InternalHandler的構(gòu)造函數(shù)使用 mainlooper,所以 handleMessage 當(dāng)然可以進(jìn)行UI 操作。

      繼續(xù)看源碼:

      private void finish(Result result) {
              if (isCancelled()) {
                  onCancelled(result);
              } else {
                  onPostExecute(result);
              }
              mStatus = Status.FINISHED;
          }

      總結(jié)一下,虛函數(shù) doInBackground 在Thread(FutureTask)run方法執(zhí)行,所以能進(jìn)行耗時(shí)操作,而InternalHanlder 通過(guò)獲得mainlooper,在 handleMessage中調(diào)用 onPostExecute 從而保證了UI 操作可以在onPostExecute執(zhí)行。這個(gè)過(guò)程實(shí)際就是模板模式。

       

       

      posted on 2017-04-25 17:34  布兜兜  閱讀(284)  評(píng)論(0)    收藏  舉報(bào)

      主站蜘蛛池模板: 国产老女人免费观看黄A∨片| 国产99视频精品免费视频36| 久久99久国产精品66| 无码抽搐高潮喷水流白浆| 在线看av一区二区三区| av大片| 国产成人高清在线重口视频 | 欧美老少配性行为| 亚洲成人av在线系列| 丰满人妻无码∧v区视频 | 国产精品露脸视频观看| 亚洲av本道一区二区| 精品国产精品中文字幕| 亚洲中文字幕av天堂| 人人爽天天碰天天躁夜夜躁| 中文字幕日韩精品国产| 安平县| 啊灬啊灬啊灬快灬高潮了电影片段| 午夜免费无码福利视频麻豆| 午夜免费福利小电影| 国产电影一区二区三区| 亚洲春色在线视频| 少妇又爽又刺激视频| 亚洲综合伊人久久大杳蕉| 国产综合色一区二区三区| 亚洲中文字幕无码久久精品1| 国产女人18毛片水真多1| 成年视频人免费网站动漫在线| 色www永久免费视频| 日本a在线播放| 日韩精品一区二区三区日韩| 国产一区二区三区导航| 高尔夫| 中文字幕人妻中文AV不卡专区| 亚洲一级特黄大片在线观看| 国产成人高清精品亚洲| 欧美大胆老熟妇乱子伦视频| 夜色福利站WWW国产在线视频| 国产不卡免费一区二区| 国产成人亚洲综合图区| 国产美女久久久亚洲综合 |