我正在尝试使用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);
}
}
答案 0 :(得分:0)
首先,默默地忽略例外永远不是一个好主意。你应该在最低限度将它们记录到logcat。它认为这是问题所在。
其次,你要多次关闭流。
你从哪里调用AsyncTask?
如果它来自某个活动并且用户离开它,则可能会在操作系统想要释放内存时终止。
如果它来自某个服务,也可以终止,但至少会在以后重新启动。如果服务是从其他进程启动的,例如同步适配器,则还应将PreExecute,PublishProgress和PostExecute代码发布到UI线程,并将应用程序循环处理程序作为消息发送。
在adition中,尝试将并发下载的数量限制为最大3.否则,可能会发生OutOfMemory。您可以使用BlockingQueue执行此操作。如果并发性不重要,请考虑使用IntentService而不是AsyncTask。
答案 1 :(得分:0)
处理下载多个文件的最佳方法是使用服务。