【发布时间】:2014-07-09 02:40:43
【问题描述】:
我在 FragmentActivity 类中创建了一个类 asyncTask:
class aysncTask extends AsyncTask<Void, Void, Void>
{
@Override
protected Void doInBackground(Void... params) {
assert(filterfiles != null);
while( !searchDone.getValue() )
{
filterfiles.searchTargetFile(android.os.Environment.getExternalStorageDirectory()+ "/");
publishProgress(); //Doesn't work here.
}
return null;
}
@Override
protected void onProgressUpdate(Void... params)
{
UpdateUI(); //Only executes as the search is done.
}
@Override
protected void onPostExecute(Void result)
{
}
}
filterfiles.searchTargetFile(~) 函数搜索本地数据,将它们添加到ArrayList: cachedData。但我等不及搜索完成,然后更新 UI。用户将等待太久。
但我不知道在哪里放置更新的 UI 代码。
不能在方法onPostExecute(Void result)里面,因为我还要等待搜索完成。
也不能在onProgressUpdate(Void params)方法内,因为一旦我调用filterfiles.searchTargetFile(~),它就会在本地系统中搜索匹配的文件。只有搜索完成后,才会调用publishProgress()。
我想到的是创建另一个线程观察cachedData,一旦找到文件,我将添加文件并更新UI。
可是我不知道怎么办?这是一个好习惯吗? 请提供一些建议的解决方案!我在这个问题上花了两天时间。
更新 我设计了一种机制来实现异步加载数据和更新 UI。当前的 搜索目标文件代码:
public void searchTargetFile(String path)
{
File dirRoot= new File( path );
File[] dirOrFile= dirRoot.listFiles();
if( dirOrFile == null) return;
for( File f : dirOrFile )
{
if( f.isDirectory() )
{
searchTargetFile( f.getAbsolutePath() );
}
else
{
for(String extName: filterFileExt)
{
if( f.getName().endsWith(extName) )
{
newDisplayFile= new DisplayFile(new String( f.getAbsolutePath() ), f.length());
this.searchedDisplayFile.add(newDisplayFile);
}
}
}
}
this.searchDone.setValue(true);
}
其中 newDisplayFile 是项目将被插入到 searchedDisplayFile。
*问题:
如何通过线程重写搜索代码,以便我可以
pause和resume它。wait()和notify()会起作用吗?应该将
wait()和notify()代码放在aysncTask 类的什么位置?
感谢任何其他更好的方法!!!
【问题讨论】:
-
正确的方法是在 onProgressUpdate 和 onPostExecute 中。两者都将在 UI 线程上调用,因此它们可以触摸 UI,并且不会出现同步问题。
-
所以你应该定义重写你的 filterfiles.searchTargetFile 方法,使用一些分页技术
-
不,我想要的场景是找到一些文件,立即更新 UI。一个线程负责搜索数据,另一个线程观察搜索到的数据,然后更新UI
-
@NguyễnHoàiNam
paging technique是什么?有什么例子吗?如何实现searchTargetFile真的让我筋疲力尽。 -
你看过这个关于Watching a Directory for Changes的教程吗?
标签: java android multithreading android-asynctask lazy-loading