Загрузить несколько файлов с помощью AsyncTask? - PullRequest
0 голосов
/ 24 декабря 2011

Я пытаюсь загрузить несколько файлов с помощью 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);
                 }
             }

Ответы [ 2 ]

0 голосов
/ 10 января 2012

Лучший способ справиться с загрузкой нескольких файлов - использовать Сервис.

0 голосов
/ 25 декабря 2011

Во-первых, никогда не стоит игнорировать исключения . Вы должны по крайней мере войти их в logcat. Кажется, это проблема.

Во-вторых, вы закрываете потоки несколько раз.

Откуда вы вызываете AsyncTask?

Если это из действия и пользователь уходит от него, это может быть прекращено, когда ОС захочет освободить память.

Если это служба, она также может быть прервана, но, по крайней мере, она будет перезапущена позже. Если служба была запущена из другого процесса, такого как адаптер синхронизации, вы также должны опубликовать код PreExecute, PublishProgress и PostExecute в потоке пользовательского интерфейса с обработчиком петли приложения в качестве сообщения.

Кроме того, попробуйте ограничить количество одновременных загрузок максимум 3. В противном случае может возникнуть OutOfMemory. Вы можете сделать это с помощью BlockingQueue. Если параллелизм не важен, рассмотрите возможность использования IntentService вместо AsyncTask.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...