使用MVVM和Firestore获取空对象引用

问题描述

我试图在我的项目中使用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());

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

解决方法

您遇到以下错误:

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

最有可能在此特定代码行:

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

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

homeViewModel.getFeeds().getValue();

返回null。这也意味着getValue()方法返回一个null的LiveData对象,的确如此,就像您的HomeViewModel类中那样,getFeeds()方法返回一个从不存在的LiveData对象。初始化。要解决此问题,请更改以下代码行:

private MutableLiveData<List<Feed>> mFeeds

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

我尝试了这个,但是仍然是相同的错误

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

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

    return mFeeds;

}
,

好的。我知道了。

我必须在FeedsRepository中添加此行,

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

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

并且从后端获取记录后,再次

mFeeds.setValue(feedsToAppend);

由于后端进程是异步的,因此需要一段时间才能提取 它将返回空对象。