使用AsyncTask下载多个文件



我正在尝试使用AsyncTask下载多个文件。我在一个AsyncTask中开始每个下载,在通知栏中有进度条,但我面临许多问题。

  1. 如果我同时下载4或5个文件,一个或多个文件

  2. 如果我下载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 ?

如果它来自一个活动,用户从它导航,可能会终止任何时间操作系统想要释放内存。

如果它来自一个服务,也可以被终止,但至少它稍后会重新启动。如果服务是从不同的进程启动的,比如Sync Adapter,你还应该将PreExecute、PublishProgress和PostExecute代码作为消息与应用程序循环处理程序一起发送到UI线程。

此外,尝试将并发下载的数量限制在最多3个。否则,可能会发生OutOfMemory。你可以用BlockingQueue来做到这一点。如果并发性不重要,可以考虑使用IntentService而不是AsyncTask。

处理下载多个文件的最好方法是使用服务。

最新更新