ParseFile.cancel () не работает – файл продолжает загружаться

Я использую parse.com Android SDK для управления некоторыми изображениями в своем приложении. Is cancel() единственный способ остановить транзакцию с сервером parse.com ?

Минимальный пример:

 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(); } } }); 

Я ожидаю, что загрузка остановится после достижения 50%, но это не так. Мой журнал в этой ситуации:

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

Единственное различие от времени, которое вы вызываете cancel() а время нет, заключается в том, что если вы отменили byte[] результат будет равен нулю. Но это действительно второстепенно, дело в том, что file продолжает потреблять полосу пропускания и, более того, накладывается на будущие загрузки, замедляя работу.

Есть ли способ остановить загрузку ParseFile? Вы видите какое-нибудь обходное решение, например, прекращение его потока? Может быть, что-то использует базовые рамки болтов? С помощью моей собственной асинхронной задачи?

Пример: метод continueWhile() может быть полезным, но я не могу понять, как его использовать.


Я хотел бы знать причину нисходящего, возможно, общего названия? Это действительно то, что я испытываю: ParseFile.cancel () не работает . И это должно, согласно официальным документам .

Комментарии предполагают, что я должен просто вызвать break . Хотя я не думаю, что это сработает, я мог бы пояснить, что код, который я опубликовал, был просто минимальным, сжатым рабочим примером, обеспечивающим как контекст, так и проблему. Я не хочу cancel() транзакцию внутри обратного вызова прогресса; Я хочу называть parseFile.cancel() всюду. Я включил обратный вызов, чтобы показать, что, хотя он должен остановиться, это не так.


Редактировать Это то, что я действительно пытаюсь сделать. Я пробовал разные способы, но это все.

 ParseFile currentFile; public void setFile(ParseFile file) { if (currentFile != null) { currentFile.cancel(); } currentFile = file; currentFile.getDataInBackground(new GetDataCallback() { ... }, new ProgressCallback() { ... // logs }); } 

С таким кодом и скажем, два больших изображения для загрузки, все идет так:

 //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. 

Solutions Collecting From Web of "ParseFile.cancel () не работает – файл продолжает загружаться"

TL; DR;

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

EDIT : похоже, это так, как видно из вашего собственного ответа. Разница заключается в версиях SDK. https://stackoverflow.com/a/32034500/2680506

Полный ответ:

Описание метода cancel() :

«Отменяет текущий сетевой запрос и обратный вызов , загружает или извлекает данные с сервера».

Мне было любопытно об этом, поэтому я сделал небольшое тестирование. Я взял свое приложение, сделал ParseFile из байтов изображения и попытался сохранить его в фоновом режиме.

Тест 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(); 

Тест 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(); 

Результаты теста 1 были похожи на то, что вы описываете, потому что файл очень маленький. Я получил только один обратный вызов прогресса на 100%, но затем он также вызвал SaveCallback .

Однако в тесте 2 метод cancel() функционирует так, как можно было бы ожидать, в результате чего не было бы журналов или обратных вызовов.

Похоже, что отмена не работает, потому что вы вызываете ее из Callback. Это согласуется с тем фактом, что вы продолжаете видеть ProgressCallbacks после того, как вы первоначально отменили свои тесты.

РЕДАКТИРОВАТЬ

Я просто загрузил изображение и протестировал отмену для себя, в методе onCreate () моей активности у меня есть этот код:

 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(); }}); 

Когда отмена прокомментирована, она войдет в GetDataCallback с заполненным байтовым массивом. Когда отмена не прокомментирована, вызов не будет выполнен. Как ни странно, ProgressCallback никогда не называется, хотя он говорит, что он гарантирован. Тем не менее, по-прежнему кажется, что отмена работает на меня.

Похоже, это была настоящая ошибка, теперь исправленная. Раньше я оставался с выпуском v1.9.2 ; Сегодня я обновил v1.10.0 и все работает отлично.