2017-08-07 105 views
0
Requirement: I want passWord to be accessible everywhere in the class. 

這個私有變量的作用域是代碼:安卓:一類

public class DetailComm extends AppCompatActivity { 

    private String passWord; 
    private Bundle bundle; 
    private Button mSendButton; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     bundle = getIntent().getExtras(); 
     mSendButton = (Button) findViewById(R.id.sendButton); 

     final Query query = mFirebaseDatabaseReference.child(<mylink>).orderByKey().equalTo(<myname>); 
     query.addValueEventListener(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) 
      { 

       for (final DataSnapshot snapshot: dataSnapshot.getChildren()) { 
        passWord = snapshot.getValue().toString(); 
        //Point 1. Toast prints correct value of passWord here// 
       } 
      } 

      @Override 
      public void onCancelled(DatabaseError databaseError) 
      { 

      } 
     }); 
     if (bundle != null) { 
      for (String key : bundle.keySet()) { 
       Toast.makeText(DetailComm.this, passWord.toString(), Toast.LENGTH_SHORT).show(); 
       //Point 2. Toast prints blank output here// 
      } 
     } 

     mSendButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       //Point 3. Toast displays correct value of passWord here!! 
      } 
     } 
    } 
} 

的問題是:同一個變量怎麼會在這裏2點難以接近?如果在第一點,當我設置密碼,它是在一個不同的類,它可能會解釋點2具有空字符串,但是,如果它也不能在點3訪問?我錯過了什麼?

我該如何讓班級中的任何地方都可以使用密碼?我將其更改爲公共變量,點2仍然顯示空值。另外,這個類是該項目中許多類中的一個。我知道肯定沒有這個變量名的其他類。

+0

您的問題似乎是一種競爭條件。當firebase完成數據獲取時,您可以設置'passWord'的值。然而,在要求firebase獲取數據並且沒有時間真正完成這項工作之後,第2點的代碼立即運行。所以,當你在第二點'passWord'完全沒有加載。第3點由點擊觸發,因此在您有時間點擊按鈕之前,Firebase有時間加載數據。您可以通過放置一些斷點並檢查他們點擊的順序來輕鬆驗證這一點。 – litelite

+0

@litelite編輯的代碼以消除混淆。 – seriouslyfunny

+0

@litelite yup,logcat時間戳顯示點2在點1之前被擊中。應該是我應該看到的第一件事。我的錯。爲了實現我的代碼的功能,我正在考慮進行firebase查詢,檢查passWord是否爲空,然後調用另一個類的新意圖,該類將包含上面的其他代碼。這是唯一的方法嗎? – seriouslyfunny

回答

0

您可以在Listener匿名類中設置值,這意味着變量只在發生事件時初始化,在您的情況下,當數據在FireBase數據庫中更改或第一次響應被傳遞時進行初始化。 但是,第2點恰好在您設置了監聽器之後發生,所以它發生在第1點之前。這就是爲什麼您給出空值。 此外,第3點也發生在lustener,所以它很不清楚哪個點將被稱爲第1點或第3點。

+0

感謝您的回答。和上面的註釋一樣qn:爲了實現我的代碼的功能,我正在考慮進行firebase查詢,檢查passWord是否爲空,然後調用另一個類的新意圖,該類將包含上面的其餘代碼。這是唯一的方法嗎? – seriouslyfunny

+0

@seriouslyfunny您可以禁用xml中的按鈕,並在l查詢完成後再次在代碼中啓用它(onDataChange()的結尾處) – Valentun