在firebase数据库上执行后台任务

时间:2017-11-30 11:56:23

标签: android firebase-realtime-database

问题就在于 - 当mProducts尝试通过onDataChange()调用从数据库获取产品时,片段会跳转到onCreateView(),使用空数组设置适配器,然后执行数据库任务。 我错过了什么或者我做错了什么? 请指出这种奇怪行为背后的原因。

感谢。

片段类

public class MainViewFragment extends Fragment {
        private static final String TAG = "MainViewFragment";
        private RecyclerView mView;
        private List<Product> mProducts;
        private DatabaseReference mRef;
        private MainViewAdapter mAdapter;

        public MainViewFragment() {

        }


        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            View v = inflater.inflate(R.layout.fragment_main_view, container, false);
            mView = (RecyclerView)v.findViewById(R.id.mainViewRecyclerView);

//            mProducts = MockData.getProductData();
            mView.setLayoutManager(new LinearLayoutManager(getActivity(),LinearLayoutManager.HORIZONTAL,false));
            mAdapter = new MainViewAdapter(mProducts,getActivity());
            mView.setAdapter(mAdapter);
            return v;
        }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mRef = FirebaseDatabase.getInstance().getReference().child("products");
        mProducts = new ArrayList<>();
        new Thread(new Runnable() {
            @Override
            public void run() {
                mRef.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        mProducts = Db.getDatabase(getActivity(),mRef).getProducts();
                    }
                    @Override
                    public void onCancelled(DatabaseError databaseError) {}
                });
            }
        }).start();

    }
}

数据库类

public class Db {
    private DatabaseReference mRef;
    private Context ctx;
    private static Db sDb;
    private List<Product> mProduct;

    public static Db getDatabase(Context ctx, DatabaseReference mRef) {
        if(sDb == null) {
            sDb = new Db(ctx,mRef);
        }
        return sDb;
    }

    private Db(Context ctx,DatabaseReference mRef) {
        this.ctx = ctx;
        this.mRef = mRef;
        this.mRef = FirebaseDatabase.getInstance().getReference().child("products");
    }

    public List<Product> getProducts() {
        mProduct = new ArrayList<>();
        mRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                Iterator<DataSnapshot> dataSnapshotIterator = dataSnapshot.getChildren().iterator();
                Product product = null;
                while (dataSnapshotIterator.hasNext()) {
                    DataSnapshot dataSnapshotChild = dataSnapshotIterator.next();
                    product = dataSnapshotChild.getValue(Product.class);
                    mProduct.add(product);
                }
            }
            @Override
            public void onCancelled(DatabaseError databaseError) {}
        });

        return mProduct;
    }
}

2 个答案:

答案 0 :(得分:0)

adapter class中,您应该拥有数据集的setter方法:

public void setData (Dataset dataset) {
  mDataset = dataset;
  notifyDataSetChanged();
}

onAttach

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    mRef = FirebaseDatabase.getInstance().getReference().child("products");
    mProducts = new ArrayList<>();
    new Thread(new Runnable() {
        @Override
        public void run() {
            mRef.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    mProducts = Db.getDatabase(getActivity(),mRef).getProducts();


                    mAdapter.setData(mProducts)

                }
                @Override
                public void onCancelled(DatabaseError databaseError) {}
            });
        }
    }).start();

答案 1 :(得分:0)

这行可能有问题

product = dataSnapshotChild.getValue(Product.class); 

没有给出期望的结果,在这种情况下,我通常用这种方式去杂化: 假设Product类有两个组件-nameprice分别是String和int,如果我在Product类中有一个构造函数,这两个部分都作为参数

String name = dataSnapshotChild.child("name").getValue(String.class);
int price= dataSnapshotChild.child("price").getValue(Integer.class);
product = new Product(name, price);
mProduct.add(product);

其中"name""price"是数据库中的节点名称