我是 Java/Android 新手,第一次接触
我开发了一个类,它使用 SetValue() 更新 Firebase DB,并在 OnComplete (DatabaseReference.CompletionListener) 出现错误时抛出异常。
在我的 Activity 中,我将对方法(在上述类中)的调用封装在 Try-Catch 中。
问题如下:
- 我无法捕获错误,因此无法在 Toast 中显示错误。
- 应用在 Debug模式下崩溃。
- 我可以在控制台中看到错误,该错误是崩溃的原因。
- 不在 Debug模式下时,应用会在 Activity 代码中立即执行以下语句,该语句会显示 toast“数据已成功保存”。
请注意,我故意更改了 firebase 安全性,以便用户无法写入。
自定义类代码:
package com.mypack.fdbmanager;
import android.app.Activity;
import android.content.Context;
import android.widget.Toast;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
public class FbDbManager {
FirebaseDatabase MyDb = FirebaseDatabase.getInstance();
DatabaseReference MyRef = MyDb.getReference("Users/User_01");
DatabaseReference MyDataRef = MyRef.child("Message");
Context MyContext;
public FbDbManager(Context context) {
MyContext = context;
}
public void UpdateUser(String valueToUpdate) {
MyDataRef.setValue(valueToUpdate, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (databaseError != null) {
throw databaseError.toException();
} else {
// Do nothing
}
}
});
}
}
这是我的 Activity 代码:
package com.mypack.fdbmanager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
FbDbManager myDbRef;
Button myButton_Send;
EditText myEdiText_Message;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myDbRef = new FbDbManager(this);
myButton_Send = findViewById(R.id.button_Send);
myEdiText_Message = findViewById(R.id.editText_Message);
myButton_Send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
UpdateUser();
}
});
}
private void UpdateUser() {
try {
myDbRef.UpdateUser(myEdiText_Message.getText().toString().trim());
Toast.makeText(getApplicationContext(), "Data saved successfully.", Toast.LENGTH_SHORT).show();
} catch (Throwable e) {
Toast.makeText(getApplicationContext(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
return;
}
}
}
这是跟踪:
V/FA: Processing queued up service tasks: 1 E/FA: Discarding data. Failed to send event to service D/EGL_emulation: eglMakeCurrent: 0xa9c06440: ver 2 0 (tinfo 0xa9c035f0) D/EGL_emulation: eglMakeCurrent: 0xa9c06440: ver 2 0 (tinfo 0xa9c035f0) W/RepoOperation: setValue at /Users/User_01/Message failed: DatabaseError: Permission denied I/zygote: Do partial code cache collection, code=61KB, data=49KB I/zygote: After code cache collection, code=61KB, data=49KB I/zygote: Increasing code cache capacity to 256KB
最佳答案
看起来您假设您的 CompletionListener 与对 UpdateUser 的调用同步执行。这不是它的工作方式。异步调用的回调 - 对 MyDataRef.setValue()
的调用始终立即返回,并且在未知的时间后调用回调。同时,您的 UpdateUser 方法在不知道任何问题的情况下返回,因为异常无法“逃逸”该函数。在调试器中运行它,并在每个方法的顶部设置断点,或者在每一行之间放置日志语句,以了解它是如何工作的。
要解决此问题,游览数据库帮助程序方法应该接受并调用异步回调。他们不应该期望阻止查询结果。您需要进行一些相当重要的重组。
关于java - 如何捕获从自定义类抛出到 Activity 中的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48414637/