如何捕获从自定义类抛出的异常到活动中?

时间:2018-01-24 04:03:55

标签: java android firebase firebase-realtime-database

我是Java / Android的新手,第一个计时器

我开发了一个使用SetValue()更新Firebase数据库的类,如果OnComplete(DatabaseReference.CompletionListener)出错,则会抛出异常。

在我的活动中,我已经在Try-Catch中调用了方法(在上面的课程中)。

问题如下:

  1. 我无法捕获错误,因此我可以在Toast中显示错误。
  2. 应用程序在调试模式下崩溃。
  3. 我可以在控制台中看到错误,此错误是崩溃的原因。
  4. 当不处于调试模式时,应用程序会在活动代码中立即执行以下语句,该代码会显示toast“数据已成功保存。”
  5. 请注意我故意改变了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
                }
            }
        });
    }
    }
    

    这是我的活动代码:

    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:处理排队的服务任务:1 E / FA:丢弃数据。   无法将事件发送到服务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:部分代码缓存   集合,代码= 61KB,数据= 49KB I / zygote:代码缓存后   集合,代码= 61KB,数据= 49KB I / zygote:增加代码缓存   容量为256KB

2 个答案:

答案 0 :(得分:1)

看起来您假设您的CompletionListener与对UpdateUser的调用同步执行。这不是它的工作方式。异步调用的回调 - 对MyDataRef.setValue()的调用总是立即返回,并且稍后调用回调未知的时间。同时,您的UpdateUser方法在不知道任何问题的情况下返回,因为异常不能“逃避”该函数。在每个方法顶部使用断点的调试器中运行它,或者在每行之间放置日志语句,以了解它是如何工作的。

要解决此问题,tour数据库帮助程序方法应该接受并调用异步回调。他们不应该期望阻止查询的结果。你有一些非常重要的重组要做。

答案 1 :(得分:0)

权限被拒绝是用户未经授权时出现的错误。更改数据库规则:

如果用户被授权或登录

,此规则将允许数据库读写
{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null"
  }
}

此规则允许数据库读写,而不检查用户是否已获得授权。

{
   "rules": {
     ".read": "true",
     ".write": "true"
   }
 }