6

जावा POJO वस्तुLiveData.getValue() कक्ष के साथ अशक्त रिटर्न

public class Section { 

    @ColumnInfo(name="section_id") 
    public int mSectionId; 

    @ColumnInfo(name="section_name") 
    public String mSectionName; 

    public int getSectionId() { 
     return mSectionId; 
    } 

    public void setSectionId(int mSectionId) { 
     this.mSectionId = mSectionId; 
    } 

    public String getSectionName() { 
     return mSectionName; 
    } 

    public void setSectionName(String mSectionName) { 
     this.mSectionName = mSectionName; 
    } 
} 

मेरे क्वेरी विधि

@Query("SELECT * FROM section") 
LiveData<List<Section>> getAllSections(); 

डीबी

final LiveData<List<Section>> sections = mDb.sectionDAO().getAllSections(); 

तक पहुँचना अगली पंक्ति मैं sections.getValue() जाँच कर रहा हूँ पर जो हमेशा मुझे शून्य देता है हालांकि मेरे पास डेटाबेस में डेटा है और बाद में मुझेमें मूल्य मिल रहा हैविधि।

sections.observe(this, new Observer<List<Section>>() { 
    @Override 
    public void onChanged(@Nullable List<Section> sections){ 

    } 
}); 

लेकिन जब मैं क्वेरी से लाइवडेटा छोड़ देता हूं तो मुझे डेटा अपेक्षित हो रहा है। क्वेरी विधि:

@Query("SELECT * FROM section") 
List<Section> getAllSections(); 

प्रवेश डीबी:

final List<Section> sections = mDb.sectionDAO().getAllSections(); 
+1

लेकिन आप 'section.getValue()' का उपयोग क्यों करना चाहते हैं, जबकि रहतेटाटा डेटा का निरीक्षण करने के लिए उपयोग किया जाता है। हो सकता है कि जब आप अगली पंक्ति में जांच कर रहे हों, डेटा लाइवटाटा में सेट नहीं है, यही कारण है कि यह आपको शून्य देता है। संक्षेप में यदि आप 'LiveData' का उपयोग नहीं करना चाहते हैं तो बस इसे 'LiveData' के बिना उपयोग करें। – Moinkhan

+1

मैं liveata का उपयोग करना चाहता हूं ... यदि 'section.getValue()' शून्य है तो मुझे डेटा के लिए एपीआई कॉल करना होगा और डेटाबेस में डालना होगा जो अंततः 'ऑन चेंज()' विधि को कॉल करेगा जहां से मुझे डेटा मिलेगा । लेकिन उस 'शून्य' मान के कारण यदि डेटाबेस और एपीआई दोनों से डेटा प्राप्त हो रहा है। – CodeCameo

उत्तर

4

मैं इस दृष्टिकोण

private MediatorLiveData<List<Section>> mSectionLive = new MediatorLiveData<>(); 
    . 
    . 
    . 

    @Override 
    public LiveData<List<Section>> getAllSections() { 
     final LiveData<List<Section>> sections = mDb.sectionDAO().getAllSections(); 

     mSectionLive.addSource(sections, new Observer<List<Section>>() { 
      @Override 
      public void onChanged(@Nullable List<Section> sectionList) { 
       if(sectionList == null || sectionList.isEmpty()) { 
        // Fetch data from API 
       }else{ 
        mSectionLive.removeSource(sections); 
        mSectionLive.setValue(sectionList); 
       } 
      } 
     }); 
     return mSectionLive; 
    } 
+0

क्या आप मेरी मदद कर सकते हैं? मुझे एक ही समस्या का सामना करना पड़ रहा है, मुझे यह कोड कहां रखना चाहिए? –

+0

आप इसे यहां पा सकते हैं ... https://github.com/codecameo/Shobdho – CodeCameo

+0

अगर किसी को भी एक ही समस्या का सामना करना पड़ रहा है, तो समाधान [MediatorLiveData] पर है (https://developer.android.com /reference/android/arch/lifecycle/MediatorLiveData.html) जो एक उप-वर्ग है जो अन्य LiveData पर देख सकता है। –

1

अगर sections.getValue() रिक्त है मैं डेटा के लिए API कॉल और डेटाबेस

में में डालने के लिए है

आप इसे onChange पर संभाल सकते हैं विधि:

sections.observe(this, new Observer<List<Section>>() { 
    @Override 
    public void onChanged(@Nullable List<Section> sections){ 
     if(sections == null || sections.size() == 0) { 
      // No data in your database, call your api for data 
     } else { 
      // One or more items retrieved, no need to call your api for data. 
     } 
    } 
}); 

लेकिन आपको बेहतर ढंग से इस डेटाबेस/तालिका प्रारंभिक तर्क को एक भंडार वर्ग में रखना चाहिए। Google's sample देखें। DatabaseCreator कक्षा देखें।

+0

मैंने पहले से ही उस उदाहरण को देखा है और इसके साथ समस्या यह है कि, जब भी एप्लिकेशन लॉन्च किया जाता है 'createDb (संदर्भ संदर्भ)' को कॉल किया जा रहा है, हालांकि इसके डेटा में प्रारंभिक रूप से 'isDatabaseCreated()' हमेशा झूठ वापस आ जाएगा। – CodeCameo

1

के माध्यम से इस समस्या का समाधान मैं इसी तरह की समस्या का समाधान हो के रूप में

इस प्रकार अपने ViewModel वर्ग

private LiveData<List<Section>> mSections; 

@Override 
public LiveData<List<Section>> getAllSections() { 

    if (mSections == null) { 
     mSections = mDb.sectionDAO().getAllSections(); 
    } 

    return mSections; 
} 

यह सभी के लिए आवश्यक है अंदर। लाइवडाटा के उदाहरण को कभी भी न बदलें।

2

अगली पंक्ति पर मैं अनुभागों को देख रहा हूं .getValue() जो हमेशा मुझे शून्य देता है हालांकि मेरे पास डेटाबेस में डेटा है और बाद में मुझे ऑन चेंज() विधि में मूल्य मिल रहा है।

मुझे लगता है कि यह एक सामान्य व्यवहार है, क्योंकि लाइवडेटा लौटने वाले प्रश्न असीमित काम कर रहे हैं।

LiveData<List<Section>> getAllSections(); 

तो colling इस विधि, आप परिणाम यहाँ

sections.observe(this, new Observer<List<Section>>() { 
@Override 
public void onChanged(@Nullable List<Section> sections){ 

} 
}); 

प्रलेखन से मिलेगा:

कक्ष मुख्य थ्रेड जब तक आप allowMainThreadQueries कहा जाता है पर डाटाबेस को ऐक्सेस की अनुमति नहीं है () निर्माता पर क्योंकि यह लंबे समय तक यूआई को संभावित रूप से लॉक कर सकता है।असीमित क्वेरी (क्वेरी जो लाइवडेटा या आरएक्सजेवा फ्लोएबल लौटाती हैं) इस नियम से मुक्त हैं क्योंकि जब आवश्यक हो तो वे पृष्ठभूमि थ्रेड पर क्वेरी को असीमित रूप से चलाते हैं।

संबंधित मुद्दे