我試圖掃描我的Android設備中的所有文件。我用了一個多線程類是這樣的:多線程意外停止在Asynctask
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。
有人能幫助我解決這個問題嗎?
我希望在DoInBackground開始運行之前掃描所有文件:) – Hanamichi 2013-03-26 20:40:27