我有一个接收要下载的 URL 的服务。该服务然后下载这些 URL 并将它们保存到 SD 卡上的文件中。
当我在下载队列中放入超过 2 个项目时,我的设备无法使用。它几乎冻结了。巨大的滞后等等。任何的想法?
源代码:
private static boolean downloading = false;
private static ArrayList<DownloadItem> downloads = new ArrayList<DownloadItem>();
/**
* called once when the service started
*/
public static void start() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
if (downloads.size() > 0 && !downloading) {
downloading = true;
DownloadItem item = downloads.get(0);
downloadSingleFile(item.getUrl(), item.getFile());
}
}
}
});
thread.start();
}
public static void addDownload(DownloadItem item) {
downloads.add(item);
}
private static void downloadSuccessfullFinished() {
if (downloads.size() > 0)
downloads.get(0).setDownloaded(true);
downloadFinished();
}
private static void downloadFinished() {
// remove the first entry; it has been downloaded
if (downloads.size() > 0)
downloads.remove(0);
downloading = false;
}
private static void downloadSingleFile(String url, File output) {
final int maxBufferSize = 4096;
HttpResponse response = null;
try {
response = new DefaultHttpClient().execute(new HttpGet(url));
if (response != null
&& response.getStatusLine().getStatusCode() == 200) {
// request is ok
InputStream is = response.getEntity().getContent();
BufferedInputStream bis = new BufferedInputStream(is);
RandomAccessFile raf = new RandomAccessFile(output, "rw");
ByteArrayBuffer baf = new ByteArrayBuffer(maxBufferSize);
long current = 0;
long i = 0;
// read and write 4096 bytes each time
while ((current = bis.read()) != -1) {
baf.append((byte) current);
if (++i == maxBufferSize) {
raf.write(baf.toByteArray());
baf = new ByteArrayBuffer(maxBufferSize);
i = 0;
}
}
if (i > 0) // write the last bytes to the file
raf.write(baf.toByteArray());
baf.clear();
raf.close();
bis.close();
is.close();
// download finished get start next download
downloadSuccessfullFinished();
return;
}
} catch (Exception e) {
// not successfully downloaded
downloadFinished();
return;
}
// not successfully downloaded
downloadFinished();
return;
}