2014-02-25 2 views
0

AsyncTask populate()을 통해 listview를 채우는 파일 관리자를 만들었습니다. 폴더에 수백 개의 폴더가있는 경우 목록보기 어댑터를 채우는 데 몇 초가 걸립니다. 그러나 폴더가 완전히 채워지기 전에 하위 폴더를 클릭 할 수 있습니다. 이 경우 채우기 프로세스가 취소되고 모든 것이 정리되고 새 채우기 프로세스가있는 새 AsyncTask가 시작됩니다.내 AsyncTask가 제대로 취소되지 않는 이유는 무엇입니까?

내 문제는 기다리지 않으면 폴더의 요소가 하위 폴더에 전달되어 폴더에 존재하지 않는 하위 폴더에 항목을 추가하는 것입니다. 다시 말하면, 오래된 AsyncTask는 내가 pop.isCancelled() 테스트를 통해 결론을 테스트 함에도 불구하고 어댑터 작성을 지속합니다. 즉, 내 점검에도 불구하고 두 개의 AsyncTask가 동시에 실행됩니다. pop.isCancelled() 대신 pop.getStatus() != Status.FINISHED을 확인하려고했지만 항상 RUNNING 상태로 실패합니다. 왜 내가 결코 FINISHED ??.

내가 뭘 잘못 했습니까 (아래 코드)? AsyncTask가 정말로 완료되었는지 어떻게 알 수 있습니까? dirs 변수는 doInBackground()에있는 isCancelled() 테스트 이후에 설정할 수 있지만 호출 프로세스에서 AsyncTask가 계속 진행되는 것을 감지하지 못하는 이유는 무엇입니까?

좋아, 당신은 내가 처음의 onPostExecute()에서 두 번째 populate()를 호출해야합니다 말할 수 있지만, AsyncTask를 취소 할 때 onPostExecute()이 실행되지 않습니다.

여기 내 간단한 코드입니다. 첫째, 호출 프로세스의 AsyncTask를의 다음 관련 부분 :

public void startPopulating(File folder) { 
    if (pop != null) { 
     pop.cancel(true); 
     while (pop != null && !pop.isCancelled()) { 
      try { 
       Thread.sleep(10); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
     pop = null; 
    } 
    pop = new populate(); 
    pop.run(folder); 
} 


class populate extends AsyncTask<Void, Boolean, Void> { 
    public void run (File dir) { 
     // Clean variables 
     if (dirs != null) dirs.clear(); 
     if (files != null) files.clear(); 
     basedir = dir; 
     execute(); 
    } 
    @Override 
    protected void onProgressUpdate(Boolean... loading) { 
     if (!loading[0]) { 
      loadAdapterData(dirs, !dirmodified); 
      dirs.clear(); 
     } 
    } 
    @Override 
    protected Void doInBackground(Void... params) { 
     dirs = new ArrayList<String>(); 
     files = new ArrayList<String>(); 

     String[] allfiles = basedir.list(); 
     String thisfile; 
     publishProgress(true); 
     Arrays.sort(allfiles, String.CASE_INSENSITIVE_ORDER); 

     for (Integer i = 0; i < allfiles.length; i++) { 
      if (isCancelled()) break; 
      thisfile = allfiles[i]; 
      if ((new File(basedir, thisfile)).isDirectory()) { 
       dirs.add(thisfile); // THIS LINE IS BEING EXECUTED AFTER THE TEST 
      } else { 
       files.add(thisfile); 
      } 
      if (i % 50 == 0 && dirs.size() > 0) publishProgress(false); 
     } 

     if (!isCancelled() && dirs.size() > 0) publishProgress(false); 

     return null; 
    } 
} 

답변

0

이 작품 것으로 보인다 : 전역 변수 (changedir)를 사용하여 AsyncTask를의 onCancelled() 방법에서 새 채우기()를 시작합니다

public void startPopulating(File dir) { 
    if (pop != null && pop.getStatus() != Status.FINISHED) { 
     changedir = dir; 
     pop.cancel(true); 
    } else { 
     changedir = null; 
     pop = new populate(); 
     pop.run(dir); 
    } 
} 


class populate extends AsyncTask<Void, Boolean, Void> { 
    [....]                               

    @Override 
    protected void onCancelled(Void args) { 
     super.onCancelled(); 
     if (changedir != null && changedir.isDirectory()) { 
      pop = new populate(); 
      pop.run(changedir); 
      changedir = null; 
     } 
    } 
} 
관련 문제