#android #multithreading #ftp
#Android #многопоточность #ftp
Вопрос:
Я создаю приложение для Android, в котором пользователь может загружать файлы с FTP-сервера. Для частей ftp я использую пакет apache.org.commons-net.
Когда я подключаюсь к серверу, я получаю список имен файлов, а затем я хочу загрузить каждый файл. Я запускаю процедуру загрузки, которая выполняется в собственном потоке.
Проблема, с которой я сталкиваюсь, заключается в том, что если у меня, скажем, 6 файлов на сервере, и я запускаю этот код на своем эмуляторе, он загрузит первые два файла, а затем просто зависнет (при этом индикатор выполнения зависает на 34%). Когда я запускаю его на своем телефоне, он загружает три файла и зависает.
Если я отлажу свой путь через код на эмуляторе, он загрузит все шесть файлов просто отлично и не зависнет.
У кого-нибудь есть идеи, в чем может быть проблема?
Заранее спасибо, Господь Иисус
Это мой код (клиент уже инициализирован):
private void downloadFiles2() {
dialog = new ProgressDialog(this);
dialog.setCancelable(true);
dialog.setMessage("Loading...");
// set the progress to be horizontal
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
// reset the bar to the default value of 0
dialog.setProgress(0);
dialog.setMax(DownloadCount);
// display the progressbar
dialog.show();
// create a thread for updating the progress bar
Thread background = new Thread (new Runnable() {
public void run() {
InputStream is = null;
try {
for (String filename : fileNames) {
is = client.retrieveFileStream(filename);
byte[] data = new byte[1024];
int x = 0;
x = is.read(data, 0, 1024);
boolean downloadIsNewer = true;
File fullPath = new File(path "/" filename);
Log.d("FTP", "Starting on " filename);
if (fullPath.exists()) {
downloadIsNewer = checkIfNewer(data, fullPath);
}
if (downloadIsNewer) {
Log.d("FTP", "Need to download new file");
FileOutputStream fos = new FileOutputStream(fullPath);
fos.write(data,0,x);
while((x=is.read(data,0,1024))>=0){
fos.write(data,0,x);
}
fileText = filename " - downloaded OK." FileParser.newline;
is.close();
client.completePendingCommand();
fos.flush();
fos.close();
}
else {
Log.d("FTP", "No need to download");
is.close();
fileText = filename " - own copy is newer." FileParser.newline;
}
// active the update handler
progressHandler.sendMessage(progressHandler.obtainMessage());
}
client.logout();
client.disconnect();
}
catch (Exception e) {
// if something fails do something smart
}
}
});
// start the background thread
background.start();
}
Handler progressHandler = new Handler() {
public void handleMessage(Message msg) {
dialog.incrementProgressBy(1);
InfoTextView.setText(fileText);
if(dialog.getProgress()== dialog.getMax())
{
dialog.dismiss();
}
}
};
Ответ №1:
Хорошо, проблема найдена:
Когда логическое значение downloadIsNewer равно false, я не вызываю client.completePendingCommand(). Когда я добавляю это перед строкой.close(), это работает как шарм.