【问题标题】:A method is not executing log.d statement方法未执行 log.d 语句
【发布时间】:2020-07-10 15:53:07
【问题描述】:

第 1 部分 - 我有一个方法 readData(),它接受 Interface FirebaseCallBack 的参数。 我在 getAdminInfo() 方法中调用 readData() 并且 Log.d 语句(第 8 行)没有被执行。我的应用程序因 空指针异常 而崩溃。

第 2 部分 - 另外 firebaseCallback.Callback(newVolunteer) 正在抛出错误 “局部变量是从内部类中访问的;需要声明为 final”。但是在堆栈溢出用户@Alex_mamo 的this 视频中,它没有显示任何错误。只是直觉我做错了什么。

public String getAdminInfo(){
    dbRef = FirebaseDatabase.getInstance().getReference("Volunteer");
    uid= mAuth.getCurrentUser().getUid();

    readData(new FirebaseCallBack() {
        @Override
        public void Callback(Volunteer data) {
            Log.d("crashfix" ," I am not executing ");
            adminStatus = data.isAdmin();
        }
    });
    return adminStatus;
}

//Read data from firebase
private void readData(FirebaseCallBack firebaseCallBack){
    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            newVolunteer.setFullName((String) dataSnapshot.child("fullName").getValue());
            newVolunteer.setAdmin((String) dataSnapshot.child("admin").getValue());
            newVolunteer.setEmail((String) dataSnapshot.child("email").getValue());
            newVolunteer.setGender((String) dataSnapshot.child("gender").getValue());
            Log.d("crashfix" ," name fetch: " + newVolunteer.getFullName());
            firebaseCallBack.Callback(newVolunteer);
        }


        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    };

    dbRef.child(uid).addListenerForSingleValueEvent(valueEventListener);
}

//Wait till the data is downloaded from firebase
private interface FirebaseCallBack{
    void Callback(Volunteer data);
}

在这一行我得到空指针异常:-

String admin = getAdminInfo();
    Log.d("crashfix" ,"inside onCreate admin" + admin);
    //checking if current user is admin
    if(admin.equals("true")){
            Toast.makeText(this,"Welcome! " + newVolunteer.getFullName() , Toast.LENGTH_SHORT).show();
            Intent intent = new Intent(this, Main2Activity.class);
            startActivity(intent);
            finish();
    }

崩溃日志:-

2020-03-30 13:41:53.060 13021-13021/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.helpinghandsorg.helpinghands, PID: 13021
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.helpinghandsorg.helpinghands/com.helpinghandsorg.helpinghands.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3123)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3266)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1957)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7099)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
    at com.helpinghandsorg.helpinghands.MainActivity.onCreate(MainActivity.java:57)
    at android.app.Activity.performCreate(Activity.java:7327)
    at android.app.Activity.performCreate(Activity.java:7318)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1275)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3103)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3266) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1957) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loop(Looper.java:214) 
    at android.app.ActivityThread.main(ActivityThread.java:7099) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) 

【问题讨论】:

    标签: java android firebase firebase-realtime-database


    【解决方案1】:

    空指针异常错误很容易解释。

    java.lang.RuntimeException:无法启动活动 ComponentInfo{com.helpinghandsorg.helpinghands/com.helpinghandsorg.helpinghands.MainActivity}:java.lang.NullPointerException:尝试调用虚拟方法'boolean java.lang .String.equals(java.lang.Object)' 在空对象引用上

    虽然您没有透露发生这种情况的代码,您似乎正试图在字符串的空引用上调用 equals 方法。我将确保检查该变量是否确实不为空。

    这就是您看不到日志的原因,因为您的应用程序正在崩溃。

    对于您的第二个问题,当在 onDataChange 方法中时,您无法访问局部变量,因此您会看到该错误。

    考虑在方法内创建一个变量,并通过回调将其传递到其他变量所在的位置。

    更新(由于 OP 的评论)

    为了接收管理员信息的更新值,您可以执行以下操作:

    public String getAdminInfo(successCallback, failureCallback){
       dbRef = FirebaseDatabase.getInstance().getReference("Volunteer");
       uid= mAuth.getCurrentUser().getUid();
    
       readData(new FirebaseCallBack() {
        @Override
          public void Callback(Volunteer data) {
            Log.d("crashfix" ," I am not executing ");
            adminStatus = data.isAdmin();
            //Here is where you insert your callback
            successCallback(adminStatus);
          }
       });
       return adminStatus;
     }
    

    代码中的某处:

    getAdminInfo(gotAdminInfoSuccess, gotAdminInfoFailure);
    
    
    private void gotAdminInfoSuccess(String adminState) {
         Log.d("crashfix" ,"inside onCreate admin" + admin);
        //checking if current user is admin
        if(adminState.equals("true")){
                Toast.makeText(this,"Welcome! " + newVolunteer.getFullName() , Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(this, Main2Activity.class);
                startActivity(intent);
                finish();
        }
    
    }
    
     private void gotAdminInfoFailure(String error) {
        //Do your failure logic here
    
     } 
    

    【讨论】:

    • 我用导致空指针异常的行更新了问题。 getAdminInfo() 不应返回 null,它正在从不为 null 的 firebase 中获取数据。
    • 对于第 2 部分 - 创建回调实例的全部目的是在 onDataChange 之外获取数据。考虑看我提供的视频,它会让你明白。
    • @VinayKharayat - getAdminInfo 是一个异步任务,因此,你不是在等待结果,这就是为什么你有一个空指针异常......
    • @VinayKharayat - 我更新了我的答案。既然对你有帮助,请注明。
    • pastebin.com/raw/F60gWG7T这是我写到现在的内容
    【解决方案2】:

    您的代码中的问题在于您仍在尝试从异步操作返回结果,这是不可能可能的。 getAdminInfo() 无法以同步方式返回该结果。基本上,您尝试从异步 API 同步返回值。这不是一个好主意。您应该按预期异步处理 API。

    话虽如此,您唯一的选择是在readData()onDataChange() 方法中使用adminStatus 状态only

    【讨论】:

    • 这是我到现在为止所做的,请你看看这个。 pastebin.com/raw/F60gWG7T
    • 您应该将data.isAdmin() 保存到一个变量中,并将其进一步用于您的逻辑,但只能在readData() 方法中使用。你代码的其他部分对我来说看起来不错。
    猜你喜欢
    • 1970-01-01
    • 2016-03-03
    • 2018-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多