2011-12-20 1 views
3

ASyncTask, 나는 onCancelled() 기능이 나는 doInBackground()isCancelled()을 사용하여 취소되는 작업을 감지 할 수 있었다 전에도라는 것을 알게 중지 cancel(false)를 호출 할 때.사용은 AsyncTask를 취소합니다 - 함수 호출 순서 -

cancel 함수의 인수를 true로 변경하려고 시도했지만 도움이되지 않았습니다. 나는이 문서를 읽을 때

, 나의 이해는 내가 doInBackground()에서 취소를 감지하는 기능에서 만 onCancelled() 기능이 onPostExecute() 대신에 호출 될 것입니다 후 반환 할 수있을 것이라고했다.

내가 누락 된 항목이 있습니까? 내가 예상 한 순서대로 일이 일어나도록 동기화 메커니즘을 추가해야합니까?

편집 :

AsyncTask<Void,Integer,Void>() { 
     ProgressDialog mProgressDialog; 

     @Override 
     protected Void doInBackground(Void... voids) { 

       for (int i=0; i<size; i++) { 
        publishProgress(i/100); 
        if (isCancelled()) { 
         Log.d(TAG, "getting out"); 
         return null; 
        } 
        // do some database operations here 
       } 

       // do some house cleaning work also here 
      } 
      return null; 
     } 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      // create the progress dialog if needed 
      mProgressDialog = new ProgressDialog(context); 
      mProgressDialog.setMessage("Do it!"); 
      mProgressDialog.setIndeterminate(false); 
      mProgressDialog.setMax(100); 
      mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { 
       public void onCancel(DialogInterface dialogInterface) { 
        cancel(false); 
       } 
      }); 
      mProgressDialog.setCancelable(true); 
      mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
      mProgressDialog.show(); 

      // create some database here 
     } 

     @Override 
     protected void onProgressUpdate(Integer... values) { 
      super.onProgressUpdate(values); 
      mProgressDialog.setProgress(values[0]); 
     } 

     @Override 
     protected void onPostExecute(Void aVoid) { 
      super.onPostExecute(aVoid); 
      mProgressDialog.dismiss(); 
     } 

     @Override 
     protected void onCancelled() { 
      super.onCancelled(); 
      Log.d(TAG, "Cancelling !"); 

      // since we are cancelling the operation, close and delete the database that was being created 
      mProgressDialog.dismiss(); 
     } 
    } 

그래서 문제가 지금, 여전히 몇 가지 작업이이 삭제되는 경우에도 데이터베이스에서 수행되고 있다는 것입니다 : 여기

코드가 구성되는 방식입니다 onCancelled()에 있습니다. 증상은 "나가기"및 "취소 중"메시지의 순서입니다. (내가 디버거와도 그것을했다 일치하지 않는 다른 스레드가 여전히 실행되는 동안 cancel() 통화가 onCancelled()에 직접가는 것 같습니다.

한 가지 가능한 이유는 this message 난 그냥 발견 ...? (I 될 수있다) 프로 요에서이 작업을 실행하고

더 ...

내가 false로 cancel() 호출에서 플래그를 설정하지만, 내가합니다 (doInBackground() 기능이 완료 또는 취소를 감지 할 수있는 기회를 가지고 있지 않는 것을 발견 그것조차 반환 진술에 결코 도달하지 않는다)

+0

AysncTask.cancel()은 부울 값을 반환합니다. 취소가 성공하면 반환 값은 무엇입니까? 사실이라면 AsycnTask가 실제로 시작되지 않은 상태에서 execute() 후에 너무 빨리 cancel()을 호출 할 것입니다. – yorkw

답변

4

그래서 몇 가지 내가 발견 (그리고 나는 무슨 일이 일어 났는지 이해 생각) onCancelled은 AyncTask.cancel() 함수가 호출 될 때 바로 호출됩니다.

그래서 내가 가진 코드는 스레드가 작동하고 있던 데이터베이스 doInBackground을 닫고 삭제한다는 것입니다. 그래서 대부분의 경우 스레드가 충돌합니다 (로그캣에서는별로 보지 못했지만 대개는 확인에 이릅니다 if (isCancelled()) ...

이 작업의 구성이 바뀌 었습니다. isCancelled이 true를 반환 할 때 doInBackground에 의해 호출 될 정리를 수행하는 별도의 함수를 만듭니다. onCancelled을 사용하지 않았습니다 ...

0

그런 식으로 코드를 작성하는 경우에만 doInBackground()에서 취소를 감지 할 수 있습니다. 이 "탐지"는 비동기 콜백을 사용하는 것이 아닙니다. 즉, doInBackground()은 취소 상태를 주기적으로 확인하고 취소가 요청 된 경우를 처리해야합니다. doInBackground() 스 니펫을 게시 할 수 있습니까? ,

내가 doInBackground 반환 후 ... 대신 onCancelled 기능을 대신 onPostExecute의 호출 될 것이라고 생각 ...