2014-02-25 47 views
0

我做了一個文件管理器,通過一個AsyncTask populate()填充列表視圖。如果文件夾中有幾百個文件夾,則填充列表視圖適配器需要幾秒鐘的時間。但是,您可以在文件夾完成填充之前單擊子文件夾。在這種情況下,填充過程將被取消,所有內容都將被清除,並且具有新填充過程的新AsyncTask將開始。爲什麼我的AsyncTask未被正確取消?

我的問題是,如果您不等待,有時文件夾中的某個元素會被傳送到子文件夾,並在該文件夾中不存在的子文件夾中添加一個條目。換句話說,舊的AsyncTask會持續寫入適配器,儘管我測試它的結論是pop.isCancelled()測試。換句話說,儘管我檢查了兩個AsyncTasks同時運行。我試圖檢查pop.getStatus() != Status.FINISHED而不是pop.isCancelled(),但它總是失敗,並且狀態爲RUNNING。爲什麼我永遠不會得到FINISHED ??。

我在做什麼錯(下面的代碼)?我怎樣才能確定一個AsyncTask真的完成了?據我所知變量可以在doInBackground()isCancelled()測試之後設置,但爲什麼調用進程沒有檢測到AsyncTask繼續?

好的,你可以說我應該從第一個的onPostExecute()調用第二個populate(),但是當AsyncTask被取消時不會被執行。

這是我的簡單代碼。首先,調用進程,那麼的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; 
     } 
    } 
} 
相關問題