使用AsyncTask下载多个文件?
问题描述:
我想使用AsyncTask下载多个文件。 我通过通知栏中的进度条开始每次下载一个AsyncTask,但是我面临很多问题。使用AsyncTask下载多个文件?
如果我下载4个或5个文件在一个或多个文件 中断,没有任何理由的同时。
如果我下载4张或5张图片,一张或多张图片损坏。
这是我使用的代码。
private class DownloadFile extends AsyncTask<String, Integer, Long>
{
int nID = 0;
int nDownloadCounter = 0;
public DownloadFile(String sFileName, int nNotificationID) {
this.nID = nNotificationID;
this.NotificationName = sFileName;
this.nDownloadCounter = 0;
}
protected void onPreExecute(){
this.sDownloadPath = sFilePathWithSubDir;
notification = new Notification(R.drawable.app_icon, "Download File", System.currentTimeMillis());
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification);
Intent notificationIntent = new Intent();
File file = new File(this.sDownloadPath + this.NotificationName);
sMediaDataType = GSUtilities.sGetFileMIMEType(this.NotificationName);
notificationIntent.setAction(android.content.Intent.ACTION_VIEW);
notificationIntent.setDataAndType(Uri.fromFile(file), sMediaDataType);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
contentView.setTextViewText(R.id.status_percent, "0%");
contentView.setTextViewText(R.id.status_fileName, this.NotificationName);
contentView.setProgressBar(R.id.status_progress, 100, 0, false);
notification.contentView = contentView;
notification.contentIntent = contentIntent;
mNotificationManager.notify(nID, notification);
}
protected Long doInBackground(String... urls) {
long retData = 0;
OutputStream fosXSPDatabse = null;
InputStream inServerResponse = null;
URLConnection oURLConnection = null;
URL oURL = null;
try
{
oURL = new URL(oFileManager.sExpiryLink);
oURLConnection = oURL.openConnection();
if (!(oURLConnection instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
oURLConnection.connect();
inServerResponse = new BufferedInputStream(oURL.openStream());
if (inServerResponse != null)
{
File fDirectory = new File(oFileManager.sAppFlesDirectory);
if (!fDirectory.exists())
{
if (!fDirectory.mkdir())
{}
}
fosXSPDatabse = new FileOutputStream(oFileManager.sAppFlesDirectory + "/" + oFileInfo.getFileName());
byte data[] = new byte[BUFFER_SIZE];
int nCount = 0;
long lTotalDownloaded = 0;
int nTotalSize = oURLConnection.getContentLength();
while ((nCount = inServerResponse.read(data)) != -1)
{
Log.d(String.valueOf(nID) + " - DoInBackground", String.valueOf(dNotificationbarProgress));
nDownloadCounter ++;
lTotalDownloaded += nCount;
dNotificationbarProgress = lTotalDownloaded * 100.0/nTotalSize;
if (this.nDownloadCounter == 20 || dNotificationbarProgress == 100) {
publishProgress(Integer.parseInt(new DecimalFormat("#.##").format(dNotificationbarProgress).split("\\.")[0]));
nDownloadCounter = 0;
}
fosXSPDatabse.write(data, 0, nCount);
}
inServerResponse.close();
fosXSPDatabse.flush();
fosXSPDatabse.close();
}
}
catch (MalformedURLException e)
{}
catch (IOException e)
{}
catch (Exception e)
{}
finally
{
try
{
inServerResponse.close();
fosXSPDatabse.flush();
fosXSPDatabse.close();
}
catch (IOException e)
{}
}
return retData;
}
protected void onProgressUpdate(Integer... progress) {
try
{
Log.d(String.valueOf(nID),"onProgressUpdate");
notification.contentView.setProgressBar(R.id.status_progress, 100, progress[0], false);
notification.contentView.setTextViewText(R.id.status_fileName, this.NotificationName);
notification.contentView.setTextViewText(R.id.status_percent, String.valueOf(progress[0]) + "%");
Intent notificationIntent = new Intent();
File file = new File(this.sDownloadPath + this.NotificationName);
sMediaDataType = GSUtilities.sGetFileMIMEType(this.NotificationName);
notificationIntent.setAction(android.content.Intent.ACTION_VIEW);
notificationIntent.setDataAndType(Uri.fromFile(file), sMediaDataType);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
notification.contentIntent = contentIntent;
mNotificationManager.notify(this.nID, notification);
}
catch(Exception e)
{}
}
protected void onPostExecute(Long result) {
notification.contentView.setTextViewText(R.id.status_fileName, "Successfully installed " + this.NotificationName);
notification.contentView.setTextViewText(R.id.status_percent, "100%");
mNotificationManager.notify(this.nID, notification);
}
}
答
处理下载多个文件的最佳方法是使用服务。
答
首先,这是不是一个好主意悄悄忽略例外。你应该至少将它们记录到logcat。它认为这是问题。
其次,您正在多次关闭流。
你从哪里调用AsyncTask?
如果它来自活动并且用户离开它,那么操作系统想要释放内存时可能会终止该操作。
如果它来自服务,也可能会终止,但至少会在稍后重新启动。如果服务是从一个不同的进程(如同步适配器)启动的,则还应将PreExecute和PublishProgress和PostExecute代码以应用程序循环处理程序作为消息发布到UI线程。
另外,尝试将并发下载数限制为最大3。否则,可能会发生OutOfMemory。你可以用BlockingQueue来做到这一点。如果并发不重要,请考虑使用IntentService而不是AsyncTask。
第一:我不删除异常它只是为了减少上面的代码。 第二:我从onclick ListView事件调用AsynkTask。 – Basbous 2011-12-25 01:43:16