在datasnapshot中设置Boolean后,将其设置为true后返回null

时间:2018-05-18 16:35:38

标签: java nullpointerexception boolean

这是我的代码:

@Echo Off
Set "src_folder=C:\Source"
Set "dst_folder=C:\Destination"
For /F "Tokens=1* Delims=[]" %%A In ('Find /N /V ""^<"chart_list.txt"') Do (
    For /F "Tokens=1* Delims=[]" %%C In ('Find /N /V ""^<"newchart_list.txt"'
    ) Do If "%%C"=="%%A" Copy /Y "%src_folder%\%%B" "%dst_folder%\%%D")

}

在日志中,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); } } 返回true。再往下,在userOnlineBoolean userOnlineBoolean为null,为什么会这样?

我尝试过很多改动,但没有任何效果。返回if-statement后为什么它为null。

我已经尝试解决这个问题几个小时,但我没有找到问题,或者看到了问题。如果您知道我的代码有什么问题,请随时与您分享。

3 个答案:

答案 0 :(得分:0)

Although I have not run the code, I suspect the issue is caused by the anonymous inner class.

Let's look at the execution of the method "onCreate":

You call the super, You make a couple of static calls. You add an event listener to an object (this is the anonymous inner class, this instance is created but the methods are not executed) Then you assign some values A couple more calls. Then you "if" on the value which is only changed in the change listener.

At this point your boolean is not set. So will throw a null pointer.

There are various ways to fix this, but hopefully be you understand the root cause.

答案 1 :(得分:0)

我设法解决了我的问题:

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

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

但我仍然不明白为什么我以前的方式错了。

答案 2 :(得分:0)

EventListener通常是异步调用的。在执行if回调之前,您的onDataChange - 子句可能正在处理

在下面找到解决问题的提案。

首先,您应该重新考虑变量userOnlineBoolean本身。考虑变量在其生命周期中可能具有的状态总是一个好主意。在这种情况下,您可以争辩说只有两种状态:用户在线或他不在线。如果是这样,您应该避免该变量为 undefined null 。立即初始化变量,即在声明时:

private boolean userOnlineBoolean = false;

如您所见,我使用了primitive boolean而不是包装类Boolean来确保它不能为空。

现在,您在onCreate()方法中获得了大量代码。我不知道你的应用程序的上下文,但该方法可能只调用一次。但是,您希望UI的相关部分不仅可以更新一次,而且可能每次更新数据库。所以代码应该进入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);
}

我认为这是一种更实用,更合理的设计。如果这对您有用,请告诉我。