【问题标题】:The global variable is not null inside an inner class but null outside全局变量在内部类内部不为空,但在外部为空
【发布时间】:2019-03-13 02:42:16
【问题描述】:

我有一个名为“myEmail”的全局变量,我想在方法中更改它的值 这样做时,变量的值确实会改变,但仅在方法内部 (我已经使用日志检查了这一点)但是在更改值后再次尝试使用变量时,它为空。

我不知道这个问题的原因是什么。我试过调用该方法 在 onCreate 上,因为我认为变量 get 在更改值之前可能会被调用,但问题仍然存在。

这是我的代码

public class messagesFragment extends Fragment {
    private FirebaseFirestore db = FirebaseFirestore.getInstance();
    private String uid = FirebaseAuth.getInstance().getUid();
    private CollectionReference messageRef = db.collection("messages");
    private View v;
    private RecyclerView recyclerView;
    private messageAdapter mAdapter;
    private String myEmail;
    private FloatingActionButton addmsg;

    public messagesFragment() {
    }
    // Creating the fragment view.
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        v = inflater.inflate(R.layout.messages_fragment, container, false);
        addmsg = (FloatingActionButton) v.findViewById(R.id.sendmsgfab);
        addmsg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getActivity(), createmessageActivity.class);
                startActivity(intent);
            }
        });

        getemail();       // Here the variable myEmail is null.
        setupRecycler();

        return v;
    }

    private void getemail(){
        DocumentReference documentReference = db.collection("users").document(uid);
        documentReference.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
            @Override
            public void onSuccess(final DocumentSnapshot documentSnapshot) {
                myEmail = documentSnapshot.get("email").toString();
              // Here the variable myEmail is not null.
            }
        });
        }

    private void setupRecycler() {
        Query query = messageRef.whereEqualTo("receiver", myEmail);
        FirestoreRecyclerOptions<message> options = new FirestoreRecyclerOptions.Builder<message>()
                .setQuery(query, message.class)
                .build();
        mAdapter = new messageAdapter(options);
        recyclerView = (RecyclerView) v.findViewById(R.id.messagesRecycler);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setAdapter(mAdapter);
    }

    @Override
    public void onStart() {
        super.onStart();
        mAdapter.startListening();
    }

    @Override
    public void onStop() {
        super.onStop();
        mAdapter.stopListening();
    }
}

【问题讨论】:

  • 尝试创建一个新变量并在onSuccess方法中分配电子邮件值
  • 再次尝试使用该变量 -> 您确定在调用onSuccess 后使用该变量吗?
  • 我在 setupRecycler 方法中再次使用了变量
  • 您的意思是在方法内部创建一个局部变量并将其分配给我的全局变量 myEmail?
  • @Skeptic94 是的,你可以试试

标签: android android-fragments android-lifecycle


【解决方案1】:

原因是myEmail 是在一个回调方法中分配的,该方法可以在调用setupRecycler() 后触发。所以你需要在onSuccesssetupRecycler()里面做检查

public class messagesFragment extends Fragment {
    private FirebaseFirestore db = FirebaseFirestore.getInstance();
    private String uid = FirebaseAuth.getInstance().getUid();
    private CollectionReference messageRef = db.collection("messages");
    private View v;
    private RecyclerView recyclerView;
    private messageAdapter mAdapter;
    private String myEmail;
    private FloatingActionButton addmsg;

    public messagesFragment() {
    }
    // Creating the fragment view.
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        v = inflater.inflate(R.layout.messages_fragment, container, false);
        addmsg = (FloatingActionButton) v.findViewById(R.id.sendmsgfab);
        addmsg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getActivity(), createmessageActivity.class);
                startActivity(intent);
            }
        });

        getemail();       // Here the variable myEmail is null.

        return v;
    }

    private void getemail(){
        DocumentReference documentReference = db.collection("users").document(uid);
        documentReference.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
            @Override
            public void onSuccess(final DocumentSnapshot documentSnapshot) {
               myEmail = documentSnapshot.get("email").toString();
               runOnUiThread(new Runnable() {
                   public void run() {
                      setupRecycler();
                   }
               });
             }
        });
     }

     private void setupRecycler() {      
          Query query = messageRef.whereEqualTo("receiver", myEmail);
          FirestoreRecyclerOptions<message> options = new FirestoreRecyclerOptions.Builder<message>()
            .setQuery(query, message.class)
            .build();
          mAdapter = new messageAdapter(options);
          recyclerView = (RecyclerView) v.findViewById(R.id.messagesRecycler);
          recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
          recyclerView.setAdapter(mAdapter);
          mAdapter.startListening();
     }

     @Override
     public void onStart() {
         super.onStart();
     }

     @Override
     public void onStop() {
         super.onStop();
        mAdapter.stopListening();
     }
}

【讨论】:

  • 我完全按照你说的做了,但是我得到了另一个错误“ java.lang.NullPointerException: Attempt to invoke virtual method 'void Adapters.messageAdapter.startListening()' on an null object reference at Fragments.messagesFragment .onStart(messagesFragment.java:85)" 似乎在调用 onstart 后调用了该方法
  • 简单,将mAdapter.startListening(); 移动到您的setupRecycler() 中,确保将其放在mAdapter = new messageAdapter(options); 之后
  • 我遇到另一个错误 :( "E/RecyclerView: 未连接适配器;跳过布局"
  • 好的,你能试着把mAdapter.startListening();放在recyclerView.setAdapter(mAdapter);之后吗?
  • 问题是我正在使用不包含空适配器构造函数的firebaseUi Recyclerview :(
【解决方案2】:

您的 getemail 方法的返回值是无效的!请在您的方法中将 String 替换为 void。

【讨论】:

    猜你喜欢
    • 2012-12-28
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 2012-12-17
    相关资源
    最近更新 更多