为什么我不能在方法之外调用变量?

时间:2019-07-24 08:12:35

标签: java android json firebase

在此解决方案的帖子中,我可以在void内部调用变量。 当我尝试在void之外调用它时,数据为空。

链接:I cant get the values from Firebase and put them in to TextView in fragment

我已经将变量定义为public。

编辑:

public class FormSendActivity extends AppCompatActivity {

// form edit text
EditText email ;
EditText perihal;
EditText deskripsi;

TextView tes;

// variabel untuk menyimpan data dari edit text menjadi string
public String emails;
public String perihals;
public String deskripsis;

//variabel untuk menampung datauser sesuai login
public String getnama;
public String getusername;

FirebaseAuth firebaseAuth;
public String uid ;

Button kirim;

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


    email = (EditText) findViewById(R.id.editText);
    perihal = (EditText) findViewById(R.id.editText2);
    deskripsi = (EditText) findViewById(R.id.editText4);
    kirim = (Button) findViewById(R.id.button);
    tes = (TextView) findViewById(R.id.textView3);

    firebaseAuth = firebaseAuth.getInstance();
    uid = firebaseAuth.getCurrentUser().getUid();

    dapatdatauser(uid);  // here i call the method of bottom, and put in to a variabel
    tes.setText(getusername); //  here i put the variabel to textview to test

    kirim.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            emails = email.getText().toString();
            perihals = perihal.getText().toString();
            deskripsis = deskripsi.getText().toString();

            Sendmail sendmail = new Sendmail(emails,perihals,deskripsis);
            FirebaseDatabase.getInstance().getReference("Sendmail")
                    .child(getusername).child("Outbox").push()
                    .setValue(sendmail).addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()){
                        Toast.makeText(FormSendActivity.this,"Data sudah terkirim !!", Toast.LENGTH_SHORT).show();
                        Intent i = new Intent(FormSendActivity.this, MainActivity.class);
                        finish();
                    }else {
                        Toast.makeText(FormSendActivity.this,"Data gagal di kirim !!", Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    });


}

public void dapatdatauser(String iduser){
    // Mendapatkan DataUsers Berdasarkan uid sesuai login
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
    DatabaseReference query = reference.child("DataUsers").child(iduser);
    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            // Memasukkan data kedalam variabel username
            getusername = dataSnapshot.child("username").getValue(String.class);

        }

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

        }
    };
    query.addListenerForSingleValueEvent(valueEventListener);
}} 

这是我的完整代码。 我首先调用方法dapatdatauser(在方法内部将其设置为变量'getusername'的值) 然后将变量设置为textview进行测试。 但输出为空。

我找到了一种将所有代码放入onCreate方法中的解决方案。然后在

public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        // Memasukkan data kedalam variabel username
        getusername = dataSnapshot.child("username").getValue(String.class);

    }

但是我只想知道,为什么我的代码最初不起作用? 谢谢

3 个答案:

答案 0 :(得分:3)

  

但是我只想知道,为什么我的代码首先不起作用?

您无法获得getusername值,因为它是异步操作。数据尚未完成从数据库的加载,因此无法访问。

答案 1 :(得分:1)

根据firestore文档 https://firebase.google.com/docs/functions/terminate-functions Cloud Firestoreasynchronous,因此基本上,在代码中您要在查询将结果设置为变量之前填充数据,因此必须在multi thread中运行它以避免出现此问题或设计操作完成后填充数据的代码。

我建议您看这篇帖子,它比您的情况更苗条。

Async with Firestore

答案 2 :(得分:0)

创建该类的对象时,将调用

OnCreate,因此它只能进行一次操作。 因此,这一次只有在onCreate中初始化变量时,才会设置它们。

OnDataChange是侦听器,在更改数据之前,不会调用此方法并设置变量。 您需要添加

tes.setText(getusername);onDataChange内,或

getusername = dataSnapshot.child("username").getValue(String.class);

onCreate之前的tes.setText(getusername);内部