2013-05-14 2 views
0

Приложение для Android всегда застревает при загрузке файла до завершения загрузки. Однако загружаемый поток наследуется от AyncTask, и он находится в фоновом режиме. Может ли кто-нибудь взглянуть и посмотреть, что не так, и как я могу изменить код, чтобы он работал?Android: Загрузить нить прикладывает приложение

private class DownloadFileTask extends AsyncTask<String, Integer, String> { 

    File destFile; 

    private boolean openAfterDownload; 
    private Exception failure; 

    public DownloadFileTask(boolean openAfterDownload) { 
     this.openAfterDownload = openAfterDownload; 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute();   
     downloadDialog.setMessage(getString(R.string.downloading)); 
     downloadDialog.show(); 
    } 

    @Override 
    protected String doInBackground(String... params) { 

     try { 

      String url = params[0]; 
      LOG.debug("Downloading: " + url); 

      String fileName = url.substring(url.lastIndexOf('/') + 1); 

      HttpParams httpParams = new BasicHttpParams(); 
      DefaultHttpClient client = new DefaultHttpClient(httpParams); 
      client.getCredentialsProvider().setCredentials(
        new AuthScope(null, -1), 
        new UsernamePasswordCredentials(user, password)); 
      HttpGet get = new HttpGet(url); 

      HttpResponse response = client.execute(get); 

      if (response.getStatusLine().getStatusCode() == 200) { 

       File destFolder = new File(config.getDownloadsFolder()); 
       if (!destFolder.exists()) { 
        destFolder.mkdirs(); 
       } 

       /** 
       * Make sure we always store downloaded files as .epub, 
       * so they show up in scans later on. 
       */ 
       if (! fileName.endsWith(".epub")) { 
        fileName = fileName + ".epub"; 
       } 

       destFile = new File(destFolder, URLDecoder.decode(fileName)); 

       if (destFile.exists()) { 
        destFile.delete(); 
       } 

       // lenghtOfFile is used for calculating download progress 
       long lenghtOfFile = response.getEntity().getContentLength(); 
       if(lenghtOfFile>=config.getAvailableSpace()) 
       { 
        this.failure = new Exception("not enough space"); 
        return null; 
       } 
       // this is where the file will be seen after the download 
       FileOutputStream f = new FileOutputStream(destFile); 

       try { 
        // file input is from the url 
        InputStream in = response.getEntity().getContent(); 

        // here's the download code 
        byte[] buffer = new byte[1024]; 
        int len1 = 0; 
        long total = 0; 

        while ((len1 = in.read(buffer)) > 0) { 

         // Make sure the user can cancel the download. 
         if (isCancelled()) { 
          return null; 
         } 

         total += len1; 
         publishProgress((int) ((total * 100)/lenghtOfFile)); 
         f.write(buffer, 0, len1); 
        } 
       } finally { 
        f.close(); 
       } 

      } else { 
       this.failure = new RuntimeException(response 
         .getStatusLine().getReasonPhrase()); 
       LOG.error("Download failed: " 
         + response.getStatusLine().getReasonPhrase()); 
      } 

     } catch (Exception e) { 
      Toast.makeText(getActivity(), e.getMessage() + "1", 
        Toast.LENGTH_LONG).show(); 
      LOG.error("Download failed.", e); 
      this.failure = e; 
     } 

     return null; 
    } 
+0

как вы начинаете задание? Вы случайно создаете новый DownloadFileTask, а затем вызываете doInBackground()? – Axarydax

+0

Я запускаю DownloadFileTask в основном потоке, после чего приложение не может работать, пока загрузка не завершится. –

ответ

0

Хотя вы работаете свою задачу в AsyncTask, но у вас есть такие строки кода:

downloadDialog.setMessage(getString(R.string.downloading)); 
    downloadDialog.show(); 

в вашем onPreExecute() метод, который в основном будет начать DialogBox перед задачей он начинает самостоятельно.

Что еще я не вижу в вашей реализации метода onPostExecute(). так что вы никогда не .dismiss() диалог. Но даже если вы это сделали, приложение все равно будет «стеком» (нормальное поведение) с этим диалогом, пока загрузка не завершится.

+0

Спасибо Эмиль. Таким образом, вы имеете в виду, что если я перемещаю следующие строки кода и отклоняю диалог в методе onPostExecute. Мое приложение больше не застрянет? downloadDialog.setMessage (getString (R.string.downloading)); downloadDialog.show(); –

+0

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

Смежные вопросы