Установка логического значения в datasnapshot возвращает значение null после установки его в значение true - PullRequest
0 голосов
/ 18 мая 2018

вот мой код:

public class ChatActivity extends AppCompatActivity {

private String titleString, userID, uploadID, imageURL, userOnlineString;
private Boolean userOnlineBoolean;
private int imageRotation;
private TextView titleCustomBar, lastSeenCustomBar;
private ImageView imageCustomBar;
private DatabaseReference mDatabaseRefUser;
private FirebaseAuth mAuth;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_chat);

    mAuth = FirebaseAuth.getInstance();
    mDatabaseRefUser = FirebaseDatabase.getInstance().getReference("Users");
    //Log.e("Lol", userOnlineString);

    mDatabaseRefUser.child(mAuth.getCurrentUser().getUid()).child("Online").addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            userOnlineBoolean = dataSnapshot.getValue(Boolean.class);
            Log.e("lol ", ""+userOnlineBoolean);

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Toast.makeText(ChatActivity.this, "some error", Toast.LENGTH_SHORT).show();
        }
    });


    Intent intent = getIntent();
    titleString = intent.getStringExtra("TITLE");
    userID = intent.getStringExtra("USERID");
    uploadID = intent.getStringExtra("UPLOADID");
    imageRotation = intent.getIntExtra("IMAGEROTATION", 0);
    imageURL = intent.getStringExtra("IMAGEURL");



    ActionBar actionBar = getSupportActionBar();
    actionBar.setDisplayShowCustomEnabled(true);

    LayoutInflater layoutInflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
    View customActionBar = layoutInflater.inflate(R.layout.chat_custombar, null);

    actionBar.setCustomView(customActionBar);

    titleCustomBar = findViewById(R.id.title_textview_id);
    lastSeenCustomBar = findViewById(R.id.last_seen_textview_id);
    imageCustomBar = findViewById(R.id.custom_image_id);

    titleCustomBar.setText(titleString);

    //getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    Glide.with(this).load(imageURL)
            .into(imageCustomBar);
    imageCustomBar.setRotation(imageRotation);
   if(userOnlineBoolean){
       userOnlineString = "Online";
    }
    lastSeenCustomBar.setText(userOnlineString);



}

@Override
protected void onStart() {
    super.onStart();

    if(mAuth.getCurrentUser() == null){
        Intent mainActivityIntent = new Intent(this, MainActivity.class);
        startActivity(mainActivityIntent);
        finish();
    }
    else {
        mDatabaseRefUser.child(mAuth.getCurrentUser().getUid()).child("Online").setValue(true);

    }
}

}

в журнале, userOnlineBoolean возвращает значение true.Далее, в if-statement userOnlineBoolean имеет значение null, почему это так?

Я перепробовал много изменений, но ничего не работает.Почему он возвращается после возврата true.

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

Ответы [ 3 ]

0 голосов
/ 18 мая 2018

Мне удалось решить мою проблему следующим образом:

public void onDataChange(DataSnapshot dataSnapshot) {
            userOnlineBoolean = dataSnapshot.getValue(Boolean.class);
            if(userOnlineBoolean){
                userOnlineString = "Online";
                settextmethod();
            }

 private void settextmethod() {
    lastSeenCustomBar.setText(userOnlineString);
}

Но я до сих пор не понимаю, почему мой предыдущий путь был неправильным.

0 голосов
/ 19 мая 2018

EventListener обычно вызывается асинхронно.Ваше if -класс, вероятно, обрабатывается до обратного вызова onDataChange.

Найдите ниже предложение по решению вашей проблемы.

Сначала вам следуетпересмотреть саму переменную userOnlineBoolean.Всегда полезно подумать о состояниях, которые переменная может иметь в течение своей жизни.В этом случае вы можете утверждать, что существует только два состояния: пользователь онлайн или нет.Если это так, вам следует избегать, чтобы эта переменная была undefined или null .Инициализируйте вашу переменную сразу, т. Е. При объявлении:

private boolean userOnlineBoolean = false;

Как видите, я использовал primitive boolean вместо класса-оболочки Boolean, чтобы убедиться, что он не может быть нулевым.

Теперь у вас есть много кода в методе onCreate().Я не знаю о контексте вашего приложения, но этот метод, вероятно, вызывается только один раз.Однако вы хотите, чтобы соответствующие части вашего пользовательского интерфейса обновлялись не только один раз, но, вероятно, каждый раз, когда ваша база данных изменяется.Таким образом, код должен входить в EventListener или, что лучше, в отдельный метод, который вызывается из EventListener.

Хорошо, вы можете удалить следующий код из метода onCreate ():

if(userOnlineBoolean){
   userOnlineString = "Online";
}
lastSeenCustomBar.setText(userOnlineString);

и поместить его в новый метод, подобный этому.

private void updateUIOnDatabaseChange() {
   userOnlineString = userOnlineBoolean ? "Online" : "";
   lastSeenCustomBar.setText(userOnlineString);
}

Обратите внимание, что я рассмотрел случай, когда статус пользователя изменяется с онлайн на не онлайн .Вот почему я заменил предложение if на троичный оператор (краткая форма для if-else).

И обновил ваш onDataChange, а также

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
  userOnlineBoolean = dataSnapshot.getValue(Boolean.class);
  updateUIOnDatabaseChange();
  Log.e("lol ", ""+userOnlineBoolean);
}

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

0 голосов
/ 18 мая 2018

Хотя я не запускал код, я подозреваю, что проблема вызвана анонимным внутренним классом.

Давайте посмотрим на выполнение метода "onCreate":

Вы вызываетесупер, вы делаете пару статических звонков.Вы добавляете прослушиватель событий к объекту (это анонимный внутренний класс, этот экземпляр создается, но методы не выполняются). Затем вы присваиваете некоторые значения еще пару вызовов.Затем вы «если» на значение, которое изменяется только в слушателе изменений.

На данный момент ваш логический не установлен.Так что бросит нулевой указатель.

Существуют различные способы исправить это, но, надеюсь, вы поймете основную причину.

...