Firebase DB / Android上的竞争条件

时间:2018-03-05 00:19:42

标签: android firebase firebase-realtime-database

我有3个类从Firebase提取数据,使用List显示它然后更新数据库。我担心我的结构会出现竞争状况。

我有MatchList类,代码是;

public class matchList extends ArrayAdapter<matches> {
private Activity context;
private List<matches> matchList;

public matchList(Activity context, List<matches> matcheslist) {
    super(context, R.layout.match_layout, matcheslist);
    this.context = context;
    this.matchList = matcheslist;
}

从fragment_fixture类调用;

@Override
public void onStart() {
    super.onStart();
    // Read from the database
    databaseMatches.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            matchesList.clear();
            for(DataSnapshot matchSnapshot : dataSnapshot.getChildren()) {
                matches match = matchSnapshot.getValue(matches.class);
                matchesList.add(match);
            }
            matchList adapter = new matchList (getActivity(), matchesList);
            listViewMatch.setAdapter(adapter);
        }
        @Override
        public void onCancelled(DatabaseError error) {
            Log.w(TAG, "Failed to read value.", error.toException());
        }
    });

我终于有另一个片段,refscorecard类;

   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_refscorecard, container, false);

    //Home Score Button
    Button homeScoreBtn = (Button) view.findViewById(R.id.btnHomeTeam);
    homeScoreBtn.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Button homeScoreBtn = (Button) getView().findViewById(R.id.btnHomeTeam);
            String homeScore = (String) homeScoreBtn.getText();
            int homeScoreAdd = Integer.valueOf(homeScore.toString()) + 1;
            homeScoreBtn.setText(String.valueOf(homeScoreAdd));

            final DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("Matches").child("Match_01");
            ref.runTransaction(new Transaction.Handler() {
                @Override
                public Transaction.Result doTransaction(MutableData mutableData) {
                    //return null;
                    Map<String, Object> updates = new HashMap<String,Object>();
                    updates.put("homeScore", 3);
                    ref.updateChildren(updates);
                    return null;
                }
                @Override
                public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot) {

                }
            });

我遇到的问题是,当我更改按钮单击时的值时,调试返回;

java.lang.NullPointerException:尝试在空对象引用上调用虚方法'java.lang.Object android.content.Context.getSystemService(java.lang.String)'

它指向的行也是(MatchList类);

super(context, R.layout.match_layout, matcheslist);

这是从fragment_fixture类调用的;

matchList adapter = new matchList (getActivity(), matchesList);

我不确定调用堆栈,这可能是我遇到此问题的原因(首先处理的是什么,onStart,onCreateView等等...这是因为数据库更新的速度,相应的读取也是如此在数据更新之前很快)。

我也尝试将数据库更新放入事务块中,但这并不能解决问题。

这似乎是更新后快速触发的Java事件(因为读取正在侦听数据更改)及其在DB更新字段时一次触发,因此它返回null而不是?

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

ValueEventListener()给出回调时,片段很可能已被破坏。 您需要删除ValueEventListener()

中的onStop()
// move to fragment class variables
ValueEventListener matchesListener = new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                matchesList.clear();
                for(DataSnapshot matchSnapshot : dataSnapshot.getChildren()) {
                    matches match = matchSnapshot.getValue(matches.class);
                    matchesList.add(match);
                }
                adapter.notifyDataSetChanged();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        };

 // in onStart()
databaseMatches.addValueEventListener(matchesListener);

// in onStop()
databaseMatches.removeEventListener(matchesListener);

您还需要移动

adapter = new matchList (getActivity(), matchesList);
listViewMatch.setAdapter(adapter);

oncreate()