Метод не выполняет оператор log.d - PullRequest
0 голосов
/ 30 марта 2020

Часть 1 - У меня есть метод readData () , который принимает аргумент интерфейса FirebaseCallBack . Я звоню readData () в getAdminInfo () метод, и оператор Log.d (8-я строка) не выполняется. И мое приложение падает с исключением нулевого указателя .

Часть 2 - Также firebaseCallback.Callback (newVolunteer) выдает ошибку "локальная переменная доступна из внутри класса; должен быть объявлен окончательным ". Но на этом видео пользователя переполнения стека @Alex_mamo не показывалось никакой ошибки. Просто интуиция, что я сделал что-то не так.

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();
    }

Cra sh Log: -

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) 

Ответы [ 2 ]

1 голос
/ 30 марта 2020

Ошибка исключения нулевого указателя довольно очевидна.

java .lang.RuntimeException: Невозможно запустить действие ComponentInfo {com.helpinghandsorg.helpinghands / com.helpinghandsorg.helpinghands.MainActivity} : j ava.lang.NullPointerException: попытка вызвать виртуальный метод 'boolean java .lang.String.equals (java .lang.Object)' для ссылки на пустой объект

Пока вы не раскрыли код, где это происходит, похоже, что вы пытаетесь вызвать метод equals для нулевой ссылки на строку. Я бы убедитесь, что эта переменная действительно не равна нулю.

По этой причине вы не видите журнал, потому что ваше приложение падает.

Для вашей второй проблемы, когда внутри onDataChange метод, вы не можете получить доступ к локальной переменной, и, следовательно, вы видите эту ошибку.

Рассмотрите возможность создания переменной внутри метода и передачи ее с обратным вызовом туда, где ваш другой v ariable resides.

ОБНОВЛЕНИЕ (из-за комментария ОП)

Чтобы получить обновленное значение для административной информации, вы можете сделать следующее :

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

 } 
0 голосов
/ 30 марта 2020

Проблема в вашем коде заключается в том, что вы все еще пытаетесь вернуть результат асинхронной операции, которая невозможна . getAdminInfo() не может вернуть этот результат синхронно. По сути, вы пытаетесь вернуть значение синхронно из API, который является асинхронным. Это не очень хорошая идея. Вы должны обрабатывать API-интерфейсы асинхронно, как и планировалось.

При этом единственный вариант, который у вас есть, - это использовать adminStatus status only внутри метода readData() или onDataChange() .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...