2012-04-30 10 views
7

Ho un semplice codice che dovrebbe svolgere un'attività, quando si fa clic sul pulsante, scaricare un file, salvarlo sulla scheda SD e aprirlo. Tutto funziona tranne durante il download, per file più grandi, la connessione si interrompe e la barra di avanzamento si blocca, quasi sempre al 20%. Ho cercato e cercato e non riesco a capire cosa fare per mantenere viva la connessione e consentire il completamento del download. Qualche idea su come mantenere attiva la connessione in modo che il download sia completato al posto dello stallo del 20%?Android - Arresta download di file di grandi dimensioni - utilizzando async/progressdialog

import java.io.BufferedInputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.URL; 
import java.net.URLConnection; 
import java.util.List; 
import android.app.Activity; 
import android.app.ProgressDialog; 
import android.content.Intent; 
import android.content.pm.PackageManager; 
import android.net.Uri; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.os.Environment; 
import android.util.Log; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 

public class DownloadTestActivity extends Activity { 

    public static final int DIALOG_DOWNLOAD_PROGRESS = 0; 
    private Button startBtn; 
    private ProgressDialog mProgressDialog; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.main); 
      mProgressDialog = new ProgressDialog(DownloadTestActivity.this); 
      mProgressDialog.setMessage("Downloading..."); 
      mProgressDialog.setIndeterminate(false); 
      mProgressDialog.setMax(100); 
      mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 

      startBtn = (Button) findViewById(R.id.startBtn); 
      startBtn.setOnClickListener(new OnClickListener() { 
        public void onClick(View v) { 
          startDownload(); 
        } 
      }); 
    } 

    private void startDownload() { 
      DownloadFile downloadFile = new DownloadFile(); 
      downloadFile 
          .execute("http://www.website.com/file.pdf"); 

    } 

    class DownloadFile extends AsyncTask<String, Integer, String> { 

      @Override 
      protected void onPreExecute() { 
        super.onPreExecute(); 
        mProgressDialog.show(); 
      } 

      @Override 
      protected void onProgressUpdate(Integer... progress) { 
        super.onProgressUpdate(progress); 
        mProgressDialog.setProgress(progress[0]); 
      } 

      @Override 
      protected String doInBackground(String... aurl) { 
        try { 
          URL url = new URL(aurl[0]); 
          URLConnection connection = url.openConnection(); 
          connection.connect(); 

          int fileLength = connection.getContentLength(); 
          Log.d("ANDRO_ASYNC", "Lenght of file: " + fileLength); 

          InputStream input = new BufferedInputStream(url.openStream()); 
          String path = Environment.getExternalStorageDirectory() 
              + "/Android/Data/" 
              + getApplicationContext().getPackageName() + "/files"; 
          File file = new File(path); 
          file.mkdirs(); 
          File outputFile = new File(file, "test1.doc"); 
          OutputStream output = new FileOutputStream(outputFile); 

          byte data[] = new byte[8192]; 
          long total = 0; 
          int count; 
          while ((count = input.read(data)) != -1) { 
            total += count; 
            publishProgress((int) (total * 100/fileLength)); 
            output.write(data, 0, count); 
          } 

          output.flush(); 
          output.close(); 
          input.close(); 
          showPdf(); 

        } catch (Exception e) { 
        } 
        return null; 
      } 

      private void showPdf() { 
        // TODO Auto-generated method stub 
      if(mProgressDialog != null){ 
        mProgressDialog.dismiss(); 
      } 

        File file = new File(Environment.getExternalStorageDirectory() 
            + "/Android/Data/" 
            + getApplicationContext().getPackageName() 
            + "/files/test1.doc"); 
        PackageManager packageManager = getPackageManager(); 
        Intent testIntent = new Intent(Intent.ACTION_VIEW); 
        testIntent.setType("application/msword"); 
        List list = packageManager.queryIntentActivities(testIntent, 
            PackageManager.MATCH_DEFAULT_ONLY); 
        Intent intent = new Intent(); 
        intent.setAction(Intent.ACTION_VIEW); 
        Uri uri = Uri.fromFile(file); 
        intent.setDataAndType(uri, "application/msword"); 
        startActivity(intent); 
      } 


    } 
} 

Modifica le informazioni logcat:

--------- beginning of /dev/log/system 
W/InputManagerService( 199): Window already focused, ignoring focus gain of:  [email protected] 
--------- beginning of /dev/log/main 
D/AndroidRuntime(20673): 
D/AndroidRuntime(20673): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<< 
D/AndroidRuntime(20673): CheckJNI is OFF 
D/AndroidRuntime(20673): Calling main entry com.android.commands.pm.Pm 
D/AndroidRuntime(20673): Shutting down VM 
D/dalvikvm(20673): GC_CONCURRENT freed 101K, 82% free 467K/2560K, paused 1ms+0ms 
D/dalvikvm(20673): Debugger has detached; object registry had 1 entries 
I/AndroidRuntime(20673): NOTE: attach of thread 'Binder Thread #3' failed 
D/AndroidRuntime(20687): 
D/AndroidRuntime(20687): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<< 
D/AndroidRuntime(20687): CheckJNI is OFF 
D/AndroidRuntime(20687): Calling main entry com.android.commands.am.Am 
I/ActivityManager( 199): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.myapp/.Activity} from pid 20687 
D/AndroidRuntime(20687): Shutting down VM 
D/dalvikvm(20687): GC_CONCURRENT freed 102K, 81% free 489K/2560K, paused 0ms+0ms 
D/jdwp (20687): Got wake-up signal, bailing out of select 
D/dalvikvm(20687): Debugger has detached; object registry had 1 entries 
I/AndroidRuntime(20687): NOTE: attach of thread 'Binder Thread #3' failed 
D/dalvikvm(20698): Late-enabling CheckJNI 
I/ActivityManager( 199): Start proc com.myapp for activity  com.myapp/.Activity: pid=20698 uid=10102 gids={1015, 3003} 
I/dalvikvm(20698): Turning on JNI app bug workarounds for target SDK version 10... 
V/PhoneStatusBar( 271): setLightsOn(true) 
D/AudioHardware( 98): AudioHardware pcm playback is going to standby. 
D/AudioHardware( 98): closePcmOut_l() mPcmOpenCnt: 1 
I/ActivityManager( 199): Displayed com.myapp/.Activity: +197ms 
W/InputManagerService( 199): Starting input on non-focused client [email protected] (uid=10098 pid=20011) 
I/ActivityManager( 199): START {cmp=com.myapp/.Choice} from pid 20698 
D/AudioHardware( 98): AudioHardware pcm playback is exiting standby. 
D/AudioHardware( 98): openPcmOut_l() mPcmOpenCnt: 0 
V/PhoneStatusBar( 271): setLightsOn(true) 
I/ActivityManager( 199): Displayed com.myapp/.Choice: +93ms 
D/ANDRO_ASYNC(20698): Lenght of file: 736768 
D/dalvikvm(20698): GC_CONCURRENT freed 103K, 3% free 9403K/9607K, paused 2ms+3ms 
W/NetworkStats( 199): found non-monotonic values; saving to dropbox 
D/dalvikvm( 199): JIT code cache reset in 5 ms (1048440 bytes 13/0) 
D/dalvikvm( 199): GC_CONCURRENT freed 1472K, 13% free 24697K/28231K, paused 12ms+14ms 
D/AudioHardware( 98): AudioHardware pcm playback is going to standby. 
D/AudioHardware( 98): closePcmOut_l() mPcmOpenCnt: 1 
I/ActivityManager( 199): Force stopping package com.myapp uid=10102 
I/ActivityManager( 199): Killing proc 20698:com.myapp/10102: force stop 
W/ActivityManager( 199): Force removing ActivityRecord{41eb1ec0 com.myapp/.Choice}: app died, no saved state 
I/InputDispatcher( 199): Dropping event because there is no focused window or focused application. 
I/ActivityManager( 199): Force finishing activity ActivityRecord{418450c8 com.myapp/.Activity} 
I/InputDispatcher( 199): Dropping event because there is no focused window or focused application. 
W/InputDispatcher( 199): channel '417b41f0  com.myapp/com.myapp/.Activity (server)' ~  Consumer closed input channel or an error occurred. events=0x8 
E/InputDispatcher( 199): channel '417b41f0 com.myapp/com.myapp.Activity (server)' ~ Channel is unrecoverably broken and will be disposed! 
W/InputDispatcher( 199): Attempted to unregister already unregistered input channel '417b41f0 com.myapp/com.myapp.Activity (server)' 
W/WindowManager( 199): Failed looking up window 
W/WindowManager( 199): java.lang.IllegalArgumentException: Requested window [email protected] does not exist 
W/WindowManager( 199): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7176) 
W/WindowManager( 199): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7167) 
W/WindowManager( 199): at com.android.server.wm.WindowState$DeathRecipient.binderDied(WindowState.java:1545) 
W/WindowManager( 199): at android.os.BinderProxy.sendDeathNotice(Binder.java:417) 
W/WindowManager( 199): at dalvik.system.NativeStart.run(Native Method) 
I/WindowManager( 199): WIN DEATH: null 
I/WindowManager( 199): WIN DEATH: Window{4175b280  com.myapp/com.myapp.Choice paused=false} 
W/WindowManager( 199): Failed looking up window 
W/WindowManager( 199): java.lang.IllegalArgumentException: Requested window [email protected] does not exist 
W/WindowManager( 199): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7176) 
W/WindowManager( 199): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7167) 
W/WindowManager( 199): at com.android.server.wm.WindowState$DeathRecipient.binderDied(WindowState.java:1545) 
W/WindowManager( 199): at android.os.BinderProxy.sendDeathNotice(Binder.java:417) 
W/WindowManager( 199): at dalvik.system.NativeStart.run(Native Method) 
I/WindowManager( 199): WIN DEATH: null 
W/InputManagerService( 199): Got RemoteException sending setActive(false) notification to pid 20698 uid 10102 
D/dalvikvm(20011): GC_CONCURRENT freed 460K, 32% free 9468K/13767K, paused 3ms+4ms 
D/AudioHardware( 98): AudioHardware pcm playback is exiting standby. 
D/AudioHardware( 98): openPcmOut_l() mPcmOpenCnt: 0 
+0

Come definisci i file "grandi"? Che misura? – Squonk

+0

Il telefono va in stop durante il download? – debracey

+0

@MisterSquonk - non troppo grande, circa 8 MB. Il massimo che dovrò scaricare sarà di circa 35MB. – user1363871

risposta

2

Ho provato a scaricare il file un paio di volte, sembra stallo di download per qualche secondo qua e là e potrebbe causare un timeout nell'applicazione. Prova a specificare i timeout in modo esplicito nell'intervallo 10-20 secondi.

private DefaultHttpClient httpclient = new DefaultHttpClient(); 
private HttpGet get = new HttpGet("your url comes here"); 

protected String[] doInBackground(Void... v) { 
    HttpParams httpParameters = new BasicHttpParams(); 
    // set the timeout in milliseconds until a connection is established 
    // the default value is zero, that means the timeout is not used 
    int timeoutConnection = 3000; 
    HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); 
    // set the default socket timeout (SO_TIMEOUT) in milliseconds 
    // which is the timeout for waiting for data 
    int timeoutSocket = 5000; 
    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); 

    httpclient.setParams(httpParameters); 

    try { 
     HttpEntity entity = httpclient.execute(get).getEntity(); 
     FileOutputStream output = new FileOutputStream(outputFile); 
     entity.writeTo(output); 
     output.close(); 
     // return something, maybe? 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } finally { 
     httpclient.getConnectionManager().shutdown(); 
    } 
    return null; 
} 
+0

Dovrei cambiare il codice in un modo diverso da timeouts secondo lei? Sono abbastanza nuovo a questo e sto cercando di imparare al volo, sarebbe troppo chiedere un esempio dei timeout? Grazie! – user1363871

+0

Ho aggiunto un esempio, si utilizza invece di HttpClient url.connection, e si deve aggiungere corretta variabile 'outputFile' per il file di output. – lenik

+0

Spero che questo aiuti qualcuno a sperimentare lo stesso problema, selezionando come risposta accettata. Grazie. – user1363871

1

Quello che sembra essere il problema è che processo 199 nel logcat sembrano essere la vostra attività, ma poi si vede:

I/ActivityManager( 199): Force stopping package com.viperean.atcassistant uid=10102 
I/ActivityManager( 199): Killing proc 20698:com.viperean.atcassistant/10102: force stop 
W/ActivityManager( 199): Force removing ActivityRecord{41eb1ec0 com.viperean.atcassistant/.atcChoice}: app died, no saved state 

(e la seconda riga mostra che sta uccidendo il tuo asynctask ...).

Non penso che ci sia qualcosa di sbagliato nel codice di download da solo. Penso che dovresti guardare più nell'attività (cosa stai facendo in quel momento accanto a quello asynctask, cosa stai visualizzando sullo schermo ... ecc ...).

Sembra anche che sia molto basso spazio nell'heap.

D/dalvikvm(20698): GC_CONCURRENT freed 103K, 3% free 9403K/9607K, paused 2ms+3ms 
D/dalvikvm( 199): JIT code cache reset in 5 ms (1048440 bytes 13/0) 
D/dalvikvm( 199): GC_CONCURRENT freed 1472K, 13% free 24697K/28231K, paused 12ms+14ms 

Quelli sono dalla raccolta dei rifiuti e accade poco prima la vostra applicazione si è schiantato, forse questo potrebbe essere un problema troppo?

+0

Penso di poterlo spiegare, dopo un po 'di tempo in attesa del download del file e non andando da nessuna parte ho fatto "lunga pressione indietro per terminare" l'app. Ecco perché è stato ucciso e rimosso ... a causa dello spazio dell'heap non so cosa dire. Ho riavviato il mio telefono e si blocca ancora. – user1363871

+0

Non so se questo significa qualcosa, ma ho provato diversi file online per il download. Prendendo la lunghezza del file in logcat e dividendo per la percentuale che il download si interrompe ottengo sempre un valore compreso tra 428.799-471.531 .. Questo significa qualcosa? Forse con il mio buffer o qualcosa del genere? – user1363871

1

ogni thread in Android viene ucciso dal sistema se non risponde per più di cinque minuti. forse dovresti considerare di scaricare come servizio o ignorare lo onProgress e ottenere la discussione per rimanere in vita

+0

Puoi mostrarmi o collegarmi a un esempio da scaricare come servizio? – user1363871

+0

mi sembra di fare il onProgress sarà una soluzione migliore – thepoosh

Problemi correlati