我正在尝试扫描我的 Android 设备中的所有文件。我使用了这样的多线程类:
public class FileScanner {
// subfolders to explore
private final Queue<File> exploreList = new ConcurrentLinkedQueue<File>();
private long fileCounter = 0;
List<File> listFile = new ArrayList<File>();
public void count() {
fileCounter++;
}
public long getCounter() {
return this.fileCounter;
}
public List<File> getListFile() {
return this.listFile;
}
int[] threads;
public FileScanner(int numberOfThreads) {
threads = new int[numberOfThreads];
for (int i = 0; i < threads.length; i++) {
threads[i] = -1;
}
}
void scan(File file) {
// add the first one to the list
exploreList.add(file);
for (int i = 0; i < threads.length; i++) {
FileExplorer explorer = new FileExplorer(i, this);
Thread t = new Thread(explorer);
t.start();
}
Thread waitToFinish = new Thread(new Runnable() {
@Override
public void run() {
boolean working = true;
while (working) {
working = false;
for (int i = 0; i < threads.length; i++) {
if (threads[i] == -1) {
working = true;
break;
}
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
waitToFinish.start();
}
public void done(int id, int counter) {
threads[id] = counter;
}
public boolean isFinished() {
for (int i = 0; i < threads.length; i++) {
if (threads[i] == -1) {
return false;
}
}
return true;
}
class FileExplorer implements Runnable {
public int counter = 0;
public FileScanner owner;
private int id;
public FileExplorer(int id, FileScanner owner) {
this.id = id;
this.owner = owner;
}
@Override
public void run() {
while (!owner.exploreList.isEmpty()) {
// get the first from the list
try {
File file = (File) owner.exploreList.remove();
if (file.exists()) {
if (!file.isDirectory()) {
count();
listFile.add(file);
} else {
// add the files to the queue
File[] arr = file.listFiles();
if (arr != null) {
for (int i = 0; i < arr.length; i++) {
owner.exploreList.add(arr[i]);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
// silent kill :)
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
owner.done(id, counter);
}
}
我在我的 Asynctask 中调用它:
私有类 FetchResidualAsynctask 扩展 AsyncTask { FileScanner fileMachine;
@Override
protected void onPreExecute() {
super.onPreExecute();
listResidualFileTemp.clear();
listResidualFileThumbnail.clear();
listResidualAppAds.clear();
listResidualAppLeftOvers.clear();
findAllStorage();
for (int i = 0; i < listStorage.size(); i++) {
fileMachine = new FileScanner(20);
fileMachine.scan(listStorage.get(i));
listFile.addAll(fileMachine.getListFile());
}
}
@Override
protected Void doInBackground(Void... params) {
numberOfFiles = listFile.size();
Log.i("numberOfFiles", "NUmber: " + numberOfFiles);
processindex = 0;
getActivity().runOnUiThread(new Runnable() {
public void run() {
mBtnClean.setText(R.string.btn_rescan);
mBtnClean.setEnabled(false);
txtResidualFile.setText("");
mProgressbar.setVisibility(View.VISIBLE);
mProgressbar.setProgress(0);
mBtnClean.setText(R.string.btn_stop);
mBtnClean.setEnabled(true);
mProgressbar.setMax(numberOfFiles);
}
});
for (int i = 0; i < listFile.size(); i++) {
getFilePath(listFile.get(i));
}
}
问题是返回的文件列表非常混乱。当我调试时,每次测试的结果都不同。第一次它返回的文件数量很少(例如:160),下一次会更大(1200)。
我认为 FileScanner fileMachine.scan() 尚未完成并强制停止运行到 DoInBackground。
有人可以帮我解决这个问题吗?