我想在将数据保存到数据库时借助 Alert.Dialog 显示进度条。但注册后程序崩溃了。
运行后报错的方法:
private void saveData() {
if (isPickPhoto) {
StorageReference mRef = FirebaseStorage.getInstance().getReference().child("ShopList Images")
.child(imgUri.getLastPathSegment());
AlertDialog.Builder builder = new AlertDialog.Builder(AddShopListActivity.this);
builder.setCancelable(false);
builder.setView(R.layout.progress_layout);
AlertDialog dialog = builder.create();
dialog.show();
mRef.putFile(imgUri).addOnSuccessListener(taskSnapshot -> {
Task<Uri> uriTask = taskSnapshot.getStorage().getDownloadUrl();
while (!uriTask.isComplete()) ;
Uri urlImage = uriTask.getResult();
imageUrl = urlImage.toString();
uploadData();
dialog.dismiss();
}).addOnFailureListener(e -> {
dialog.dismiss();
});
} else {
Toast.makeText(this, "Yükleme yapmak için galeriden bir resim seç", Toast.LENGTH_SHORT).show();
}
}
但是当我用它来更新数据时它工作正常。
完美运行的方法:
private void updateData() {
AlertDialog.Builder builder = new AlertDialog.Builder(AddShopListActivity.this);
builder.setCancelable(false);
builder.setView(R.layout.progress_layout);
AlertDialog dialog = builder.create();
dialog.show();
if (isPhotoChanged) {
StorageReference storageReference = FirebaseStorage.getInstance().getReference().child("ShopList Images").child(imgUri.getLastPathSegment());
storageReference.putFile(imgUri).addOnSuccessListener(taskSnapshot -> {
Task<Uri> uriTask = taskSnapshot.getStorage().getDownloadUrl();
while (!uriTask.isComplete()) ;
Uri urlImage = uriTask.getResult();
imageUrl = urlImage.toString();
uploadData();
dialog.dismiss();
}).addOnFailureListener(e -> {
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
});
} else {
imageUrl = oldImageUrl;
uploadData();
dialog.dismiss();
}
}
在 saveData() 方法中使用 AlertDialog 可以做什么?
我想用 Dialog.Alert.builder 显示进度条。但它在保存数据后崩溃了。
LogCat屏幕:
这个特殊的异常似乎有点难以解释,但是这里很好地解释了导致这个错误的原因。 tl; dr:对于您的情况,错误似乎是
dialog
比它被调用的 Activity
还长,因为 .dismiss()
-call 有时没有正确发出。
现在缩小根范围似乎有点棘手,因为
Activity
过早关闭的原因不会显示在日志中。 (有报道称在上面 SO 帖子的几个答案下的评论中观察到这一点。)dialog
被关闭之前关闭您的方法的原因,请注释掉 dialog.show()
,重现导致此错误发生的步骤并再次检查日志。
当您尝试在活动完成后显示对话框时,会发生 WindowLeaked 错误。要解决此问题,请在显示对话框之前使用 isFinishing() 检查活动是否仍在运行:
private void saveData() {
if (isPickPhoto) {
//...
if (!AddShopListActivity.this.isFinishing()) {
dialog.show();
}
mRef.putFile(imgUri).addOnSuccessListener(taskSnapshot -> {
//...
if (!AddShopListActivity.this.isFinishing()) {
dialog.dismiss();
}
}).addOnFailureListener(e -> {
if (!AddShopListActivity.this.isFinishing()) {
dialog.dismiss();
}
});
} else {
//...
}
}
这将通过确保仅在活动处于活动状态时显示和关闭对话框来防止崩溃。