2015-08-09 16 views
12

Sto utilizzando l'SDK Android parse.com per gestire alcune immagini nella mia app. cancel() è l'unico modo per interrompere una transazione con il server parse.com?ParseFile.cancel() non funziona: il file continua a essere scaricato

Esempio minimo:

final ParseFile file = ... ; 
file.getDataInBackground(new GetDataCallback() { 

    //called when loading is done 
    @Override 
    public void done(byte[] bytes, ParseException e) { 
     Log.e(TAG, String.valueOf(bytes == null)); 
    } 

}, new ProgressCallback() { 

    //called to notify progress 
    @Override 
    public void done(Integer integer) { 
     Log.e(TAG, String.valueOf(integer)); 
     if (integer > 50) { 
      file.cancel(); 
     } 
    } 
}); 

mi aspetterei che il carico si ferma dopo il 50% è raggiunto, ma non è così. Il mio log in questa situazione sarebbe:

1 
2 
3 
.... 
49 
50 
51 
.... 
98 
99 
100 
true 

L'unica differenza dai tempi si chiamano cancel() e volte non lo fai, è che se è stata annullata il risultato byte[] è nullo. Ma questo è davvero secondario, il punto qui è che file continua a consumare larghezza di banda e, inoltre, si sovrappone a download futuri, rallentando le cose.

C'è un modo per veramente stop ParseFile caricamento? Vedi qualche soluzione, come fermare il suo thread? Forse qualcosa che usa la struttura dei bulloni sottostante? Usando il mio compito asincrono?

Esempio: il metodo continueWhile() potrebbe essere utile, ma non riesco a capire come usarlo.


Mi piacerebbe conoscere il motivo del downvote, forse il titolo comune? Questo è davvero quello che sto vivendo: ParseFile.cancel() non funziona. E dovrebbe, secondo il funzionario docs.

I commenti suggeriscono che dovrei semplicemente chiamare break. Anche se non penso che funzionerebbe, potrei chiarire che il codice che ho postato era solo un esempio di lavoro minimo e conciso che forniva sia il contesto che il problema. Non voglio la transazione cancel() dall'interno del callback di avanzamento; Voglio chiamare parseFile.cancel() da tutte le parti. Inserisco il callback di avanzamento per mostrare che, mentre dovrebbe fermarsi, non lo è.


Edit Questo è quello che sto cercando di fare. Ho provato diversi modi, ma questo è tutto.

ParseFile currentFile; 
public void setFile(ParseFile file) { 

    if (currentFile != null) { 
     currentFile.cancel(); 
    } 

    currentFile = file; 
    currentFile.getDataInBackground(new GetDataCallback() { 
     ... 
    }, new ProgressCallback() { 
     ... // logs 
    }); 
} 

Con tale codice e dire, due grandi immagini da scaricare, le cose vanno come:

//calling setFile(file1) 
1 
2 
3 
... 
20 
21 
22 
//calling setFile(file2), thus also calling file1.cancel() 
1 
2 
23 //file1 going on! 
3 
24 
4 
25 
... //things get slower and this screws up progress bars and such. 
+0

Hai provato a utilizzare l'interruzione invece di file.cancel() ;? – Want2bExpert

+0

@ Want2bExpert è questo il motivo del downvote? Non ho provato perché non è questo il punto. Ho bisogno (e dovrei essere in grado di, secondo il 'cancel()' [documentazione] (https://parse.com/docs/android/api/com/parse/ParseFile.html#cancel())) per cancellare la transazione chiamandola sull'istanza del file, 'parseFile.cancel()', non solo dall'interno del callback (che non ha senso). Il codice nella mia domanda era un esempio minimale che mostrava il problema. – natario

+0

Non ho votato per nessuna risposta o commento. – Want2bExpert

risposta

6

Sembra che questo sia stato un bug reale, ora risolto. Ero solito rimanere con la versione v1.9.2; oggi ho aggiornato a v1.10.0 e tutto funziona bene.

+0

Hai trovato un bug report per questo, o ha funzionato solo dopo aver aggiornato? – AdamMc331

+0

Ho provato ad aggiornare per questo particolare motivo e ha funzionato, ma non c'era alcun riferimento a questo bug nel registro delle modifiche. Forse c'è un database di bug da qualche parte. – natario

9

TL; DR;

L'unica conclusione che posso trarre a questo punto è che c'è una differenza nelle nostre implementazioni che sta causando l'annullamento del fallimento.

MODIFICA: questo sembra essere il caso visto nella propria risposta. La differenza sono le versioni dell'SDK.https://stackoverflow.com/a/32034500/2680506

risposta completa:

La descrizione per il metodo di cancel(): "annulla la richiesta di rete attuale e callback se è il caricamento o il recupero dei dati dal server"

Ero curioso di questo, quindi ho fatto un piccolo test per conto mio. Ho preso la mia app, ho creato uno ParseFile dai byte di un'immagine e ho tentato di salvarlo sullo sfondo.

test 1

Bitmap file = BitmapFactory.decodeResource(context.getResources(), R.drawable.background); 
    ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
    file.compress(Bitmap.CompressFormat.PNG, 100, stream); 
    byte[] byteArray = stream.toByteArray(); 
    final ParseFile myTestFile = new ParseFile(byteArray); 
    myTestFile.saveInBackground(new SaveCallback(){ 

     @Override 
     public void done(ParseException e) { 
      if(e == null) 
      { 
       Log.i(null, "Done saving."); 
      } 

     } 

    }, new ProgressCallback(){ 

     @Override 
     public void done(Integer progress) { 
      Log.i(null, "Progress at " + progress + "%"); 
      if(progress > 50) 
      { 
       myTestFile.cancel(); 
      } 
     }}); 
    //myTestFile.cancel(); 

prova 2

Bitmap file = BitmapFactory.decodeResource(context.getResources(), R.drawable.background); 
    ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
    file.compress(Bitmap.CompressFormat.PNG, 100, stream); 
    byte[] byteArray = stream.toByteArray(); 
    ParseFile myTestFile = new ParseFile(byteArray); 
    myTestFile.saveInBackground(new SaveCallback(){ 

     @Override 
     public void done(ParseException e) { 
      if(e == null) 
      { 
       Log.i(null, "Done saving."); 
      } 

     } 

    }, new ProgressCallback(){ 

     @Override 
     public void done(Integer progress) { 
      Log.i(null, "Progress at " + progress + "%"); 
     }}); 
    myTestFile.cancel(); 

I risultati per Test 1 erano simili a ciò che si descrive, perché il file è molto piccolo ho avuto solo un callback corso al 100%, ma quindi ha anche invocato lo SaveCallback.

In Test 2, tuttavia, il metodo cancel() sembra funzionare come ci si aspetterebbe, con la conseguenza di non avere registri o callback.

Sembra che l'annullamento non funzioni perché si sta chiamando dal callback. Ciò è coerente con il fatto che continui a vedere ProgressCallback dopo aver annullato in origine nei tuoi test.

EDIT

Ho appena caricato un'immagine e testato annullare per me stesso, nel metodo onCreate() della mia attività ho questo codice:

ParseQuery<ParseObject> newQuery = ParseQuery.getQuery("TestObject"); 
newQuery.findInBackground(new FindCallback<ParseObject>(){ 
    @Override 
    public void done(List<ParseObject> objects, ParseException e) 
    { 
     ParseFile myTestFile = objects.get(0).getParseFile("file"); 
     myTestFile.getDataInBackground(new GetDataCallback() 
     { 
      @Override 
      public void done(byte[] data, ParseException e) 
      { 
       Log.i(null, "Download finished"); 
      } 
     }, 
     new ProgressCallback() 
     { 

      @Override 
      public void done(Integer percentDone) 
      { 
       Log.i(null, "Download at " + percentDone + "%"); 
      } 
     }); 
     //myTestFile.cancel(); 
    }}); 

quando Annulla è commentato, Sarà immettere GetDataCallback con un array di byte popolato. Quando l'annullamento non viene commentato, non si verificherà alcuna richiamata. Stranamente, il ProgressCallback non viene mai chiamato anche se dice che è garantito. Tuttavia, sembra ancora che l'annullamento funzioni per me.

+0

Grazie per la risposta. Ho modificato la mia domanda con il codice che desidero veramente utilizzare e 'cancel()' non funziona davvero. Una differenza tra noi potrebbe essere che sto usando 'getData()' mentre tu sei 'save()' ing. – natario

+0

Questa è solo un'ipotesi, ma il problema potrebbe essere che si sta sostituendo il file corrente prima che venga cancellato, ci sono più thread che vanno qui e molti accessi simultanei e cose strane potrebbero succedere a seconda dell'implementazione. Se currentFile non è null, non lo sostituirò ma memorizzerò un nuovo riferimento. Ti suggerirei anche di testare te stesso cercando di annullare il download subito dopo averlo avviato e vedere se funziona in questo modo. –

+0

get versus save sono entrambe operazioni di rete che utilizzano la stessa implementazione di base quindi dubito che farebbe la differenza. –

Problemi correlati