【问题标题】:Getting null object reference using MVVM & Firestore使用 MVVM 和 Firestore 获取空对象引用
【发布时间】:2020-08-11 10:41:11
【问题描述】:

这么多天以来,我一直在尝试在我的项目中使用 MVVM。但无法实现。

我的代码:

FeedRepository.java

public class FeedsRepository {

private static FeedsRepository instance;

private List<Feed> feedsToAppend = new ArrayList<>();


public static FeedsRepository getInstance() {
    if (instance == null) {
        instance = new FeedsRepository();
    }
    return instance;
}

public MutableLiveData<List<Feed>> getFeeds() {

    MutableLiveData<List<Feed>> mFeeds = new MutableLiveData<>();

    Query query;
    query = feedsRef.whereEqualTo("userID", currentUID).whereEqualTo("not_interested", false)
            .orderBy("created_at", Query.Direction.DESCENDING).limit(10);
    query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            if (task.isSuccessful()) {

                QuerySnapshot snapshot = task.getResult();

                if (snapshot.isEmpty()) {

                } else {

                    List<DocumentSnapshot> documents = snapshot.getDocuments();

                    for (DocumentSnapshot doc: documents) {
                        final Feed feed = doc.toObject(Feed.class);
                        feed.setFeedID(doc.getId());
                        feed.setFeedAvailable(true);

                        feedsToAppend.add(feed);
                        System.out.println("Feed: " + feed.getFeedID());
                    }

                    System.out.println("Total feeds to append: " + feedsToAppend.size());
                    mFeeds.setValue(feedsToAppend);

                }

            }
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {

        }
    });

    return mFeeds;

}

HomeViewModel.java

public class HomeViewModel extends ViewModel {

    private MutableLiveData<List<Feed>> mFeeds;
    private FeedsRepository repo;

    public void init() {

        if (mFeeds != null) {
            return;
        }
        repo = FeedsRepository.getInstance();
        mFeeds = repo.getFeeds();
    }

    public LiveData<List<Feed>> getFeeds() {

        return mFeeds;

    }

}

HomeFragment.java

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

        feedsRecycleView = view.findViewById(R.id.feeds_recycler_view);

        homeViewModel = ViewModelProviders.of(this).get(HomeViewModel.class);
        homeViewModel.init();

        homeViewModel.getFeeds().observe(getViewLifecycleOwner(), new Observer<List<Feed>>() {
            @Override
            public void onChanged(List<Feed> feeds) {
                System.out.println("Feed adapter feeds: "+feeds.size());
                mFeeds = feeds;
                feedAdapter.notifyDataSetChanged();
            }
        });

        List<Feed> testFeeds = homeViewModel.getFeeds().getValue();
        System.out.println("Test feeds are : " + testFeeds.size());

        feedAdapter = new FeedAdapter(getContext(), homeViewModel.getFeeds().getValue());
        feedsRecycleView.setAdapter(feedAdapter);

        feedsRecycleView.setHasFixedSize(true);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
        linearLayoutManager.setStackFromEnd(true); //newer posts will be shown on top
        linearLayoutManager.setReverseLayout(true);
        feedsRecycleView.setLayoutManager(linearLayoutManager);

        return view;
    
    }

我得到错误

"尝试调用接口方法'int java.util.List.size()' 空对象引用”

在这条线上

List<Feed> testFeeds = homeViewModel.getFeeds().getValue();

feedAdapter = new FeedAdapter(getContext(), homeViewModel.getFeeds().getValue());

请任何人告诉我我在哪里犯错了。

【问题讨论】:

    标签: java android firebase mvvm google-cloud-firestore


    【解决方案1】:

    您收到以下错误:

    “尝试在空对象引用上调用接口方法'int java.util.List.size()'”

    最有可能出现在这行代码中:

    System.out.println("Test feeds are : " + testFeeds.size());
    

    这是因为您的testFeeds 对象是null,这意味着:

    homeViewModel.getFeeds().getValue();
    

    返回null。这也意味着getValue() 方法返回一个 LiveData 对象,即null,这确实是在您的HomeViewModel 类中的情况,getFeeds() 方法返回一个从未初始化的 LiveData 对象。要解决这个问题,请更改以下代码行:

    private MutableLiveData<List<Feed>> mFeeds
    

    private MutableLiveData<List<Feed>> mFeeds = new MutableLiveData<>();
    

    【讨论】:

    • 顺便说一句,我已经在 Repository 中初始化了 MutableLiveData,所以通过调用 repo.getFeeds() 应该返回空提要。
    • testFeeds 仍然为空吗?
    • 是的,它仍然为空。
    • 您是否尝试在 if-else 语句结束后将这一行 return mFeeds; 移入您的 FeedRepository 类?作为onComplete 方法的最后一行。是这样吗?
    【解决方案2】:

    好的。我想通了。

    我必须在 FeedsRepository 中添加这一行,

     public MutableLiveData<ArrayList<Feed>> getFeeds() {
    
        MutableLiveData<ArrayList<Feed>> mFeeds = new MutableLiveData<>();
        mFeeds.setValue(feedsToAppend);
        ......
    

    从后端获取记录后,再次

    mFeeds.setValue(feedsToAppend);
    

    由于后端进程是异步的,并且需要时间来获取 它会返回空对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-19
      • 2012-09-18
      • 2023-02-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多