2014-02-25 33 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; 
     } 
    } 
} 
相关问题