英文:
Getting null object reference using MVVM & Firestore
问题
I'm trying to use MVVM in my project for so many days. But unable to achieve it.
My code:
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**
```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;
}
I get error
"Attempt to invoke interface method 'int java.util.List.size()' on a
null object reference"
on this line
List<Feed> testFeeds = homeViewModel.getFeeds().getValue();
and
feedAdapter = new FeedAdapter(getContext(), homeViewModel.getFeeds().getValue());
Please anyone tell me where am I making mistake.
英文:
I'm trying to use MVVM in my project for so many days. But unable to achieve it.
My code:
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;
}
I get error
> "Attempt to invoke interface method 'int java.util.List.size()' on a
> null object reference"
on this line
List<Feed> testFeeds = homeViewModel.getFeeds().getValue();
and
feedAdapter = new FeedAdapter(getContext(), homeViewModel.getFeeds().getValue());
Please anyone tell me where am I making mistake.
答案1
得分: 1
以下是翻译好的内容:
你遇到了以下错误:
> “尝试在空对象引用上调用接口方法'int java.util.List.size()'
很可能是在以下这行代码出现的问题:
System.out.println("Test feeds are : " + testFeeds.size());
这是因为你的 testFeeds
对象是 null
,这意味着:
homeViewModel.getFeeds().getValue();
返回了 null
。这也意味着 getValue()
方法返回了一个空的 LiveData 对象,而事实上在你的 HomeViewModel
类中,getFeeds()
方法返回了一个从未初始化的 LiveData 对象。要解决这个问题,请更改以下代码行:
private MutableLiveData<List
为
private MutableLiveData<List
英文:
You are getting the following error:
> "Attempt to invoke interface method 'int java.util.List.size()' on a null object reference"
Most likely at this particular line of code:
System.out.println("Test feeds are : " + testFeeds.size());
And this is because your testFeeds
object is null
, meaning that:
homeViewModel.getFeeds().getValue();
Return null
. This also means that getValue()
method returns a LiveData object that is null
, which is indeed the case as in your HomeViewModel
class the getFeeds()
method returns a LiveData object which is never initialized. To solve this, please change the following line of code:
private MutableLiveData<List<Feed>> mFeeds
to
private MutableLiveData<List<Feed>> mFeeds = new MutableLiveData<>();
答案2
得分: 0
我已经弄清楚了。
我不得不在FeedsRepository中添加这一行,
public MutableLiveData<ArrayList<Feed>> getFeeds() {
MutableLiveData<ArrayList<Feed>> mFeeds = new MutableLiveData<>();
mFeeds.setValue(feedsToAppend);
然后在从后端获取记录之后再次执行
mFeeds.setValue(feedsToAppend);
由于后端处理是异步的,并且需要时间来获取,它可能会返回空对象。
英文:
Okay. I have figured it out.
I had to add this line in FeedsRepository,
public MutableLiveData<ArrayList<Feed>> getFeeds() {
MutableLiveData<ArrayList<Feed>> mFeeds = new MutableLiveData<>();
mFeeds.setValue(feedsToAppend);
......
and after fetching records from backend, again
mFeeds.setValue(feedsToAppend);
As the backend process is asynchronous, and would take time to fetch
it would return with null object.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论