如何取消Firebase StorageTask?

时间:2018-08-25 11:53:12

标签: android firebase kotlin firebase-storage

我正在将一些图像上传到Firebase存储,每当单击“取消”按钮时,我都需要取消该过程,但是我无法处理取消,应用崩溃了。这是我的代码和logcat错误:

代码:

buttonCancel.setOnClickListener{
     uploadTask.cancel()
}

val storageRef = FirebaseStorage.getInstance().reference
for (path in pathsList){
        val imgRef = storageRef.child("${Calendar.getInstance().timeInMillis}.jpg")
        val fileUri = Uri.fromFile(File(path))
        uploadTask = imgRef.putFile(fileUri)
        try {
            uploadTask.addOnCompleteListener {
                p0 -> val downloadUri = p0.result.toString()
                //do sth with download uri
            }
        }
        catch (ex: Exception){
            Toast.makeText(this, "upload canceled", Toas.LENGHT_SHORT).show
            break
        }
}

Logcat错误:

08-25 18:20:59.149 22419-23332/packagename E/StorageException: StorageException has occurred.
The operation was cancelled.
 Code: -13040 HttpResult: 0
08-25 18:20:59.158 22419-22419/packagename D/AndroidRuntime: Shutting down VM
08-25 18:20:59.161 22419-22419/packagename E/AndroidRuntime: FATAL EXCEPTION: main
Process: packagename, PID: 22419
com.google.android.gms.tasks.RuntimeExecutionException: com.google.firebase.storage.StorageException: The operation was cancelled.
    at com.google.firebase.storage.StorageTask.getResult(Unknown Source)
    at com.google.firebase.storage.StorageTask.getResult(Unknown Source)
    at packagename.myFragment$myMethod$1$1.onComplete(myFragment.kt:348)
    at com.google.firebase.storage.zzq.zza(Unknown Source)
    at com.google.firebase.storage.zzac.zza(Unknown Source)
    at com.google.firebase.storage.zzaf.run(Unknown Source)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6776)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
 Caused by: com.google.firebase.storage.StorageException: The operation was cancelled.
    at com.google.firebase.storage.UploadTask.onCanceled(Unknown Source)
    at com.google.firebase.storage.StorageTask.zza(Unknown Source)
    at com.google.firebase.storage.StorageTask.zza(Unknown Source)
    at com.google.firebase.storage.StorageTask.zzk(Unknown Source)
    at com.google.firebase.storage.StorageTask.zzl(Unknown Source)
    at com.google.firebase.storage.zzx.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:762)
08-25 18:20:59.428 22419-23333/packagename E/StorageUtil: error getting token java.util.concurrent.ExecutionException: com.google.firebase.internal.api.FirebaseNoSignedInUserException: Please sign in before trying to get a token.

如何捕获此异常?(请注意,我正在for循环中执行此操作,我不知道它可能会有所不同)

2 个答案:

答案 0 :(得分:0)

在失败上传中像这样做

uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

            uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
                @Override
                public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
                    if (!task.isSuccessful()) {
                        throw task.getException();
                    }
                    return postImageUri.getDownloadUrl();
                }
            }).addOnCompleteListener(new OnCompleteListener<Uri>() {
                @Override
                public void onComplete(@NonNull Task<Uri> task) {
                    if (task.isSuccessful()) {
                        Uri downloadUri = task.getResult();
                        //getting url
                    }
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    //failure to get the url
                }
            });
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            // here you will get the exception
            e.printStackTrace();
        }
    });

答案 1 :(得分:0)

问题在于,当没有可用的结果可获取时,您正在onCompleteListener中调用getResult()。相反,您应该将onCompleteListener(它接收成功和失败的所有结果)替换为onSuccessListener和onFailureListener。 onSuccessListener将仅接收成功的结果,因此您始终可以安全地调用getResult()而不会引发异常。

请阅读Play Services Task API documentation,以详细了解任务的工作方式。