디자인 모델 측면 에서 AsyncTask - 템 플 릿 방법 모델 알 아 보기

6283 단어
AsyncTask 는 안 드 로 이 드 로 포 장 된 경량급 비동기 류 로 사용법 이 간단 합 니 다.그러나 이 간단 한 비동기 류 에는 많은 지식 이 포함 되 어 있다. 본 고 는 주로 디자인 모델 인 템 플 릿 방법 으로 AsyncTask 에서 의 사용 을 간단하게 분석 하고 자 한다.먼저 템 플 릿 방법의 정 의 를 말 합 니 다.
템 플 릿 방법: 특정한 문제 에 대해 그 해결 절 차 는 이미 알 고 있 고 고정 되 어 있 지만 절차 중의 구체 적 인 해결 방식 은 서로 다른 수요 가 다 를 수 있 기 때문에 템 플 릿 방법 (고정, 변경 할 수 없 음) 이 나 타 났 다. 이 방법 에서 절차 (방법) 를 정 의 했 고 자 류 는 필요 에 따라 해당 하 는 절차 방법 을 다시 쓰 면 된다.
AsyncTask 의 간단 한 사용 을 살 펴 보 겠 습 니 다.
//         
 new AsyncTask(){
      @Override
      protected Void doInBackground(Void... params) {
            return null;
      }
}.execute();

우선 우리 가 살 펴 본 AsyncTask 구조 함수:
/**
 *  AsyncTask  ,   UI       ,      
 */
public AsyncTask() {
        //WorkerRunnable Callable     
        mWorker = new WorkerRunnable() {
            public Result call() throws Exception {
                    ...      
                    //  doInBackground
                    result = doInBackground(mParams);
                    ...      
                } ...      
                finally {
                    //   Hanlder        
                    postResult(result);
                }
                return result;
            }
        };

        //          Runnable    
        mFuture = new FutureTask(mWorker) {
            @Override
            protected void done() {
                try {
                    //       ,        postResult
                    postResultIfNotInvoked(get());
                } ...      
            }
        };
    }

이 를 통 해 알 수 있 듯 이 AsyncTask 의 구조 함수 에서 주로 두 개의 대상 을 구 조 했 습 니 다. mWorker 와 mFuture, mWorker 는 Callable 인터페이스 실현 류 이 고 주로 call 방법 을 재 작성 하 며 잠시 후에 온라인 풀 에서 실 행 될 때 호출 됩 니 다.mFuture 는 Future Task 인터페이스 구현 클래스 로 run 방법 을 다시 쓰 고 Future Task 는 Runnable 의 하위 클래스 입 니 다.
비동기 임 무 를 수행 하 는 데 는 모두 두 가지 방법 이 있 습 니 다. execute 와 execute OnExecutor 가 있 습 니 다. 그러나 두 가 지 는 실제 적 으로 같 습 니 다. execute 도 execute OnExecutor 를 호출 하기 때문에 우 리 는 execute OnExecutor 방법 을 직접 봅 니 다.
 /**
  *       ,   UI    ,         
  */
  @MainThread
  public final AsyncTask executeOnExecutor(Executor exec,
            Params... params) {
        ...      
        //     ,        ( UI  )
        onPreExecute();
        
        ...              

        //         (  mFuture          ),   mFuture run  。
        //                             ,        
        exec.execute(mFuture);

        return this;
  }

execute OnExecutor 에서 exec, 즉 스 레 드 풀 을 사용 하여 execute 를 실행 하면 기본 적 인 SerialExecutor 로 분석 합 니 다.
 public synchronized void execute(final Runnable r) {
            mTasks.offer(new Runnable() {
                public void run() {
                    try {  
                        //       Runnable run  (    mFuture run  )
                        r.run();
                    } finally {  
                        //          
                        scheduleNext();
                    }
                }
            });
            if (mActive == null) {
                scheduleNext();
            }
        }

SerialExecutor 의 execute 방법 에서 우 리 는 r. run, r 즉 우리 앞 에 전 달 된 mFuture 를 호출 하 는 것 을 보 았 습 니 다. 구조 중의 mFuture 의 run 방법 을 보 겠 습 니 다.
public void run() {
        ...              
        //  Callable call  (     AsyncTask        mWorker)
        result = c.call();
        ...          
    }

c. 즉, 우리 에 게 전 달 된 mWorker 인 스 턴 스 입 니 다. mWorker 의 call 방법 은:
 public Result call() throws Exception {
                    ...      
                    //  doInBackground
                    result = doInBackground(mParams);
                    ...      
                } ...      
                finally {
                    //   Hanlder        
                    postResult(result);
                }
                return result;
            }

doInBackground 를 호출 한 것 을 볼 수 있 습 니 다. 마지막 으로 post Result 방법 도 호출 됩 니 다. post Result 는 UI 스 레 드 기반 Handler 대상 (Internal Handler 인 스 턴 스) 을 사용 하여 결 과 를 UI 스 레 드 로 보 냅 니 다.
 private Result postResult(Result result) {
    @SuppressWarnings("unchecked")
    //  Handler    Message  ,      ,     (Message       ,      Message      )
    Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult(this, result));
    message.sendToTarget();
    return result;
}

사용자 정의 Hanlder 클래스:
private static class InternalHandler extends Handler {
        //  UI  Handler
        public InternalHandler() {
            super(Looper.getMainLooper());
        }

        @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
        @Override
        public void handleMessage(Message msg) {
            AsyncTaskResult> result = (AsyncTaskResult>) msg.obj;
            switch (msg.what) {
                case MESSAGE_POST_RESULT:
                    //     ,  finish
                    result.mTask.finish(result.mData[0]);
                    break;
                case MESSAGE_POST_PROGRESS:
                    //      (             ,    publishProgress    )
                    result.mTask.onProgressUpdate(result.mData);
                    break;
            }
        }
    }

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

위의 프로 세 스 를 통 해 알 수 있 듯 이 AsyncTask. execute 의 실행 프로 세 스: onPreExecute () -- > doInBackground () -- > publishProgress () -- > onProgressUpdate () -- > onPostExecute ().이 모든 절 차 는 execute / execute OnExecutor 에서 시 작 된 것 으로 final 유형 으로 정의 되 었 습 니 다. 이 유 는 비동기 작업 의 절차 가 고정 되 어 있 기 때 문 입 니 다. 바로 상기 몇 가지 절차 입 니 다. 그러나 구체 적 으로 이 비동기 작업 이 무엇 을 하려 면 하위 클래스 가 자신의 수요 에 따라 확인 하고 해당 하 는 방법 을 다시 쓰 면 됩 니 다.이것 이 바로 템 플 릿 방법 모델 의 간단 한 분석 이다. 안 드 로 이 드 에서 템 플 릿 디자인 모델 을 많이 사 용 했 지만 우 리 는 신경 쓰 지 않 았 다. 예 를 들 어 Activity / Fragment 의 생명 주기 등 이다.부족 한 점 이 있 으 면 지적 하고 함께 발전 하 세 요.

좋은 웹페이지 즐겨찾기