简体   繁体   English

为什么此方法在另一个方法完成之前运行?

[英]Why this method runs before the other method finishes?

I am kinda new to Android programming. 我是Android编程的新手。 I am building a simple application and I have a "follow-unfollow" concept on it. 我正在构建一个简单的应用程序,并且上面有一个“关注-不关注”概念。 What I simply want is, if the current user follows the user he/she is exploring, I want him/her to see "unfollow" button. 我只想要的是,如果当前用户关注他/她正在探索的用户,我希望他/她看到“取消关注”按钮。 If not following, there should be a "follow" button. 如果不遵循,则应该有一个“关注”按钮。 On my UserProfileActivity class I have a method called onPrepareOptionsMenu() and inside this method I can set the buttons. 在我的UserProfileActivity类上,我有一个名为onPrepareOptionsMenu()的方法,在此方法内,我可以设置按钮。

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    MenuItem follow = menu.findItem(R.id.action_follow);
    MenuItem unfollow = menu.findItem(R.id.action_unfollow);
    Bundle bundle = this.getIntent().getExtras();
    if(isFollowing(bundle.getString("userid")) == true){
        follow.setVisible(false);
        unfollow.setVisible(true);
    }
    else{
        follow.setVisible(true);
        unfollow.setVisible(false);
    }
    return super.onPrepareOptionsMenu(menu);
}

Also, I have another method called isFollowing() and it returns a boolean "true" if current user follows the other user, it returns "false" if not. 另外,我还有一个名为isFollowing()的方法,如果当前用户跟随另一个用户,则返回布尔值“ true”,否则返回“ false”。 It is the simplest way that I have thought to solve this issue. 这是我想解决此问题的最简单方法。

    public boolean isFollowing(String userID){
    isFollowingResult = false;

    firebaseDatabase = FirebaseDatabase.getInstance();
    databaseReference = firebaseDatabase.getReference();
    final DatabaseReference followingData = databaseReference.child("followingData");

    followingData.child(currentUser.getUid()).child(userID).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if(dataSnapshot.exists())
                isFollowingResult = true;
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
    return isFollowingResult;
}

When I run this, and when I click on a user's profile onPrepareOptionsMenu() method is called and inside it isFollowing() method is called. 当我运行它时,以及当我单击用户的个人资料时,将调用onPrepareOptionsMenu()方法,并在其内部调用isFollowing()方法。 The problem is, it does not wait for the isFollowing() method to run and finish running and it immediately sees it as "false" and always shows "follow" button. 问题是,它不等待isFollowing()方法运行并完成运行,并且立即将其视为“ false”,并且始终显示“ follow”按钮。 Any suggestion would be appreciated. 任何建议,将不胜感激。

Thanks. 谢谢。

There are multiple issues with the code. 代码存在多个问题。

Firstly, your isFollowing() function is setting up the listener, on the data field, but it'll only get called when the data changes. 首先,您的isFollowing()函数正在数据字段上设置侦听器,但是只有在数据更改时才会被调用。 In this case, you may only want to read the data once: https://firebase.google.com/docs/database/android/read-and-write#read_data_once 在这种情况下,您可能只想读取一次数据: https : //firebase.google.com/docs/database/android/read-and-write#read_data_once

Secondly, the use of a listener implies asynchronicity. 其次,使用侦听器意味着异步性。 Meaning, you'll need to wait until you get the callback later in order to get the value you want. 意思是,您需要等到以后获得回调才能获取所需的值。

The ideal solution in order to maintain responsiveness of your app is to maintain a local "copy" of the value in your database with a listener that constantly updates that value. 为了保持应用程序的响应能力,理想的解决方案是使用不断更新该值的侦听器维护数据库中值的本地“副本”。 That way, you can query the state of your variable quickly (since it's stored/replicated locally) and still be up to date with your database (with the listener). 这样,您可以快速查询变量的状态(因为它是在本地存储/复制的),并且仍可以与数据库(使用侦听器)保持最新。

This will also prevent each "read" from going all the way to the service and back and also remove the need for your UI to wait to render correctly (accurately). 这也将防止每个“读取”一直到服务再返回,也不需要UI等待正确(准确)呈现。

Make follow and unfollow the fields of the class. followunfollow班级的字段。 Then change their visibility in onDataChange(DataSnapshot) method. 然后在onDataChange(DataSnapshot)方法中更改其可见性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM