पेजिंग 2 लाइब्रेरी की खास जानकारी Android Jetpack का हिस्सा है.

पेजिंग लाइब्रेरी की मदद से, एक ही समय में डेटा के छोटे-छोटे हिस्सों को लोड करके दिखाया जा सकता है. मांग पर आंशिक डेटा लोड करने से नेटवर्क बैंडविथ और सिस्टम का इस्तेमाल कम हो जाता है संसाधन.

इस गाइड में लाइब्रेरी के कई सैद्धांतिक उदाहरण दिए गए हैं. साथ ही, और इसके काम करने के तरीक़े के बारे में खास जानकारी पाएं. इस लाइब्रेरी से जुड़े सभी उदाहरण देखने के लिए फ़ंक्शन को ठीक करने के लिए, अतिरिक्त संसाधन सेक्शन में भी जाना जा सकता है.

सेटअप

अपने Android ऐप्लिकेशन में पेजिंग कॉम्पोनेंट इंपोर्ट करने के लिए, इन्हें जोड़ें ये आपके ऐप्लिकेशन की build.gradle फ़ाइल पर निर्भर करती हैं:

Groovy

dependencies {
  def paging_version = "2.1.2"

  implementation "androidx.paging:paging-runtime:$paging_version" // For Kotlin use paging-runtime-ktx

  // alternatively - without Android dependencies for testing
  testImplementation "androidx.paging:paging-common:$paging_version" // For Kotlin use paging-common-ktx

  // optional - RxJava support
  implementation "androidx.paging:paging-rxjava2:$paging_version" // For Kotlin use paging-rxjava2-ktx
}

Kotlin

dependencies {
  val paging_version = "2.1.2"

  implementation("androidx.paging:paging-runtime:$paging_version") // For Kotlin use paging-runtime-ktx

  // alternatively - without Android dependencies for testing
  testImplementation("androidx.paging:paging-common:$paging_version") // For Kotlin use paging-common-ktx

  // optional - RxJava support
  implementation("androidx.paging:paging-rxjava2:$paging_version") // For Kotlin use paging-rxjava2-ktx
}

लाइब्रेरी आर्किटेक्चर

यह सेक्शन, पेजिंग लाइब्रेरी के मुख्य कॉम्पोनेंट के बारे में बताता है और उन्हें दिखाता है.

पेज वाली सूची

पेजिंग लाइब्रेरी का मुख्य कॉम्पोनेंट, PagedList क्लास लोड होती है आपके ऐप्लिकेशन के डेटा के हिस्से या पेज. जितना ज़्यादा डेटा की ज़रूरत होगी, ज़रूरी है मौजूदा PagedList ऑब्जेक्ट में पेज किया जाएगा. अगर लोड किए गए किसी डेटा में बदलाव होता है, तो PagedList का इंस्टेंस, मॉनिटर किए जा सकने वाले डेटा होल्डर को LiveData या RxJava2 पर आधारित ऑब्जेक्ट है. जैसे PagedList ऑब्जेक्ट जनरेट हुए, आपके ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) का कॉन्टेंट, आपके यूज़र इंटरफ़ेस (यूआई) कंट्रोलर के मुताबिक लाइफ़साइकल.

नीचे दिया गया कोड स्निपेट दिखाता है कि अपने ऐप्लिकेशन के व्यू मॉडल को कैसे कॉन्फ़िगर किया जा सकता है PagedList ऑब्जेक्ट के LiveData होल्डर का इस्तेमाल करके डेटा को लोड और प्रज़ेंट करें:

Kotlin

class ConcertViewModel(concertDao: ConcertDao) : ViewModel() {
    val concertList: LiveData<PagedList<Concert>> =
            concertDao.concertsByDate().toLiveData(pageSize = 50)
}

Java

public class ConcertViewModel extends ViewModel {
    private ConcertDao concertDao;
    public final LiveData<PagedList<Concert>> concertList;

    // Creates a PagedList object with 50 items per page.
    public ConcertViewModel(ConcertDao concertDao) {
        this.concertDao = concertDao;
        concertList = new LivePagedListBuilder<>(
                concertDao.concertsByDate(), 50).build();
    }
}

डेटा

PagedList का हर इंस्टेंस लोड होता है आपके ऐप्लिकेशन के डेटा का अप-टू-डेट स्नैपशॉट DataSource ऑब्जेक्ट. डेटा फ़्लो अपने ऐप्लिकेशन के बैकएंड या डेटाबेस से PagedList ऑब्जेक्ट में ले जाएं.

इस उदाहरण में, रूम परसिस्टेंस लाइब्रेरी में सेव किया जा सकता है, लेकिन अगर किसी अन्य तरीके से आपका डेटा सेव करना है, तो आप भी अपना डेटा सोर्स फ़ैक्ट्री.

Kotlin

@Dao
interface ConcertDao {
    // The Int type parameter tells Room to use a PositionalDataSource object.
    @Query("SELECT * FROM concerts ORDER BY date DESC")
    fun concertsByDate(): DataSource.Factory<Int, Concert>
}

Java

@Dao
public interface ConcertDao {
    // The Integer type parameter tells Room to use a
    // PositionalDataSource object.
    @Query("SELECT * FROM concerts ORDER BY date DESC")
    DataSource.Factory<Integer, Concert> concertsByDate();
}

PagedList ऑब्जेक्ट में डेटा लोड करने के तरीके के बारे में ज़्यादा जानने के लिए, यहां जाएं: पेज वाला डेटा लोड करने के तरीके की गाइड देखें.

यूज़र इंटरफ़ेस (यूआई)

PagedList क्लास, आइटम लोड करने के लिए PagedListAdapter RecyclerView. ये क्लास एक साथ काम करके, कॉन्टेंट के लोड होने पर उसे प्रीफ़ेच करती हैं और उसे फ़ेच करती हैं कॉन्टेंट में बदलाव करने और ऐनिमेशन के ज़रिए कॉन्टेंट दिखाने की सुविधा.

ज़्यादा जानने के लिए, पेज के तौर पर सेव करने की जानकारी दिखाने के तरीके के बारे में गाइड देखें सूचियां.

अलग-अलग डेटा आर्किटेक्चर के साथ काम करें

पेजिंग लाइब्रेरी इन डेटा आर्किटेक्चर के साथ काम करती है:

  • सिर्फ़ बैकएंड सर्वर से दिखाया जाता है.
  • इन्हें सिर्फ़ डिवाइस के डेटाबेस में सेव किया जाता है.
  • अन्य सोर्स का कॉम्बिनेशन, जिसमें डिवाइस पर मौजूद डेटाबेस को कैश मेमोरी के तौर पर इस्तेमाल किया जाता है.

पहली इमेज में दिखाया गया है कि इन सभी आर्किटेक्चर स्थितियों में डेटा कैसे फ़्लो करता है. तय सीमा में सिर्फ़-नेटवर्क या सिर्फ़-डेटाबेस-ओनली सलूशन के मामले में, डेटा सीधे आपके ऐप्लिकेशन का यूज़र इंटरफ़ेस (यूआई) मॉडल. अगर आपने मिले-जुले तरीके का इस्तेमाल किया है, तो आपके बैकएंड सर्वर, डिवाइस पर मौजूद डेटाबेस में, और फिर आपके ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) मॉडल में. समय-समय पर, हर डेटा फ़्लो के एंडपॉइंट में, लोड होने में डेटा खत्म हो जाता है, इसके बाद, यह डेटा देने वाले कॉम्पोनेंट से ज़्यादा डेटा का अनुरोध करता है. उदाहरण के लिए, डिवाइस में मौजूद डेटाबेस में डेटा खत्म हो जाने पर, वह ज़्यादा डेटा का अनुरोध करता है को भी सेव करता है.

डेटा फ़्लो के डायग्राम
पहली इमेज. हर उस आर्किटेक्चर से डेटा कैसे फ़्लो करता है जिसे पेजिंग लाइब्रेरी सहायता

इस सेक्शन के बाकी हिस्से में, हर कॉन्फ़िगरेशन को कॉन्फ़िगर करने के सुझाव दिए गए हैं डेटा फ़्लो के इस्तेमाल का उदाहरण.

सिर्फ़ नेटवर्क

बैकएंड सर्वर से डेटा दिखाने के लिए, लोड करने के लिए, Retrofit API जानकारी को आपके अपने कस्टम DataSource में ऑब्जेक्ट शामिल है.

सिर्फ़ डेटाबेस

अपना RecyclerView सेट अप करें स्टोरेज के बारे में ज़्यादा जानने के लिए, रूम परसिस्टेंस का इस्तेमाल करें लाइब्रेरी चुनें. इस तरह, जब भी डेटा को आपके ऐप्लिकेशन के डेटाबेस में डाला या बदला जाता है, तो ये बदलाव अपने-आप उस RecyclerView में भी दिखेगा जो इस डेटा को दिखा रहा है.

नेटवर्क और डेटाबेस

डेटाबेस को देखने के बाद, आप का डेटाबेस डेटा न होने की वजह से PagedList.BoundaryCallback. फिर आप अपने नेटवर्क से और आइटम फे़च कर सकते हैं और उन्हें डेटाबेस. अगर आपके यूज़र इंटरफ़ेस (यूआई) में डेटाबेस देखा जा रहा है, तो आपको बस इतना ही करना है.

नेटवर्क की गड़बड़ियों को ठीक करना

दिखाए जा रहे डेटा को फ़ेच या पेज करने के लिए, नेटवर्क का इस्तेमाल करते समय पेजिंग लाइब्रेरी के लिए, यह ज़रूरी है कि आप नेटवर्क को किसी भी "उपलब्ध है" या "उपलब्ध नहीं है" ऐसा इसलिए होता है, क्योंकि इसकी वजह से कई कनेक्शन रुक-रुककर चलते हैं या फ्लेकी:

  • हो सकता है कि कोई खास सर्वर, नेटवर्क के अनुरोध का जवाब न दे.
  • मुमकिन है कि डिवाइस धीमे या कमज़ोर नेटवर्क से कनेक्ट किया गया हो.

इसके बजाय, आपके ऐप्लिकेशन को हर अनुरोध की जांच करनी चाहिए और उसे जहां नेटवर्क उपलब्ध नहीं है, वहां जितना संभव हो सके उतने अच्छे तरीके से. उदाहरण के लिए, तो आपके पास "फिर से कोशिश" करने का विकल्प है इस बटन पर क्लिक करके, उपयोगकर्ता चुन सकते हैं कि डेटा रीफ़्रेश करने के लिए काम नहीं करता. अगर डेटा पेजिंग के चरण के दौरान कोई गड़बड़ी होती है, तो बेहतर होगा कि फिर से कोशिश करें पेजिंग अनुरोध को अपने आप किया जाता है.

अपना मौजूदा ऐप्लिकेशन अपडेट करना

अगर आपका ऐप्लिकेशन पहले से ही किसी डेटाबेस या बैकएंड सोर्स का डेटा इस्तेमाल कर रहा है, तो पेजिंग लाइब्रेरी से मिलने वाली सुविधा पर सीधे अपग्रेड किया जा सकता है. इस सेक्शन में, ऐसे ऐप्लिकेशन को अपग्रेड करने का तरीका बताया गया है जिसका डिज़ाइन एक जैसा है.

पसंद के मुताबिक पेजिंग समाधान

अगर आपके ऐप्लिकेशन में डेटा के छोटे सबसेट लोड करने के लिए, कस्टम फ़ंक्शन का इस्तेमाल किया जाता है डेटा सोर्स में, इस लॉजिक को PagedList क्लास. के इंस्टेंस PagedList, सामान्य डेटा सोर्स के साथ बिल्ट-इन कनेक्शन ऑफ़र करता है. ये इंस्टेंस इसके लिए अडैप्टर भी देते हैं RecyclerView ऑब्जेक्ट जो को अपने ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) में भी शामिल किया जा सकता है.

पेजों के बजाय सूचियों का इस्तेमाल करके लोड किया गया डेटा

यदि आप अपने यूज़र इंटरफ़ेस (यूआई) के लिए बैकिंग डेटा संरचना के रूप में किसी इन-मेमोरी सूची का उपयोग करते हैं इसलिए, डेटा अपडेट देखने के लिए, PagedList क्लास, अगर संख्या सूची में मौजूद आइटम बड़े बन सकते हैं. PagedList के इंस्टेंस इनमें से किसी का भी इस्तेमाल कर सकते हैं LiveData<PagedList> या आपके ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) पर डेटा अपडेट भेजने के लिए, Observable<List> का इस्तेमाल करें. इससे, कॉन्टेंट लोड होने में कम समय लगेगा और मेमोरी के इस्तेमाल को दिखाता है. बेहतर होगा, एक List को बदला जा रहा है आपके ऐप्लिकेशन में PagedList ऑब्जेक्ट वाले ऑब्जेक्ट के लिए, ऐप्लिकेशन में किसी बदलाव की ज़रूरत नहीं है ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) का स्ट्रक्चर या डेटा अपडेट करने वाला लॉजिक.

CursorAdapter का इस्तेमाल करके डेटा कर्सर को सूची के तौर पर जोड़ें

आपका ऐप्लिकेशन CursorAdapter का इस्तेमाल कर सकता है Cursor से मिले डेटा को ListView. इस स्थिति में आपको आम तौर पर ListView से RecyclerView: ऐसा करने के लिए, ऐप्लिकेशन की सूची यूज़र इंटरफ़ेस (यूआई) कंटेनर का इस्तेमाल करें. इसके बाद, Cursor को बदल दें कॉम्पोनेंट, जिसमें रूम या PositionalDataSource, इस बात पर निर्भर करता है कि Cursor के इंस्टेंस SQLite डेटाबेस.

कुछ स्थितियों में, जैसे कि Spinner, आपको सिर्फ़ अडैप्टर देना है वह भी ऐसा कर सकता है. इसके बाद, लाइब्रेरी उस अडैप्टर में लोड किए गए डेटा को इकट्ठा करती है और आपके लिए डेटा दिखाता है. इन परिस्थितियों में, अपने अडैप्टर का डेटा LiveData<PagedList>, फिर रैप करें यह सूची, ArrayAdapter ऑब्जेक्ट में है इससे पहले कि लाइब्रेरी क्लास इन आइटम को यूज़र इंटरफ़ेस (यूआई) में इनफ़्लेट करे.

AsyncListUtil का इस्तेमाल करके, कॉन्टेंट को एसिंक्रोनस रूप से लोड करें

अगर इसका इस्तेमाल किया जा रहा है, तो AsyncListUtil ऑब्जेक्ट को जानकारी के समूहों को एसिंक्रोनस रूप से लोड और प्रदर्शित करने के लिए, पेजिंग लाइब्रेरी तो डेटा को और आसानी से लोड किया जा सकता है:

  • यह ज़रूरी नहीं है कि आपका डेटा एक जगह पर ही दिखे. पेजिंग लाइब्रेरी से, आपको नेटवर्क से मिली कुंजियों का इस्तेमाल करके सीधे अपने बैकएंड से डेटा इकट्ठा कर सकते हैं.
  • आपके डेटा की संख्या बहुत ज़्यादा हो सकती है. पेजिंग लाइब्रेरी का इस्तेमाल करके, डेटा को तब तक पेजों में सेव रखता है, जब तक कोई डेटा मौजूद नहीं रहता.
  • अपने डेटा पर आसानी से नज़र रखी जा सकती है. पेजिंग लाइब्रेरी ऐसा डेटा जो आपके ऐप्लिकेशन के ViewModel ने मॉनिटर किए जा सकने वाले डेटा स्ट्रक्चर में रखा है.

डेटाबेस के उदाहरण

नीचे दिए गए कोड स्निपेट, सभी हिस्सों को रखने के कई संभावित तरीके दिखाते हैं एक साथ कैसे काम करते हैं.

LiveData का इस्तेमाल करके, पेज किए गए डेटा पर नज़र रखना

नीचे दिया गया कोड स्निपेट, सभी हिस्सों को एक साथ काम करते हुए दिखाता है. कॉन्सर्ट के तौर पर इवेंट को डेटाबेस में जोड़ा, हटाया या बदला जाता है, तो इवेंट RecyclerView है ये टूल अपने-आप और बेहतर तरीके से अपडेट होते हैं:

Kotlin

@Dao
interface ConcertDao {
    // The Int type parameter tells Room to use a PositionalDataSource
    // object, with position-based loading under the hood.
    @Query("SELECT * FROM concerts ORDER BY date DESC")
    fun concertsByDate(): DataSource.Factory<Int, Concert>
}

class ConcertViewModel(concertDao: ConcertDao) : ViewModel() {
    val concertList: LiveData<PagedList<Concert>> =
            concertDao.concertsByDate().toLiveData(pageSize = 50)
}

class ConcertActivity : AppCompatActivity() {
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // Use the 'by viewModels()' Kotlin property delegate
        // from the activity-ktx artifact
        val viewModel: ConcertViewModel by viewModels()
        val recyclerView = findViewById(R.id.concert_list)
        val adapter = ConcertAdapter()
        viewModel.concertList.observe(this, PagedList(adapter::submitList))
        recyclerView.setAdapter(adapter)
    }
}

class ConcertAdapter() :
        PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) {
    fun onBindViewHolder(holder: ConcertViewHolder, position: Int) {
        val concert: Concert? = getItem(position)

        // Note that "concert" is a placeholder if it's null.
        holder.bindTo(concert)
    }

    companion object {
        private val DIFF_CALLBACK = object :
                DiffUtil.ItemCallback<Concert>() {
            // Concert details may have changed if reloaded from the database,
            // but ID is fixed.
            override fun areItemsTheSame(oldConcert: Concert,
                    newConcert: Concert) = oldConcert.id == newConcert.id

            override fun areContentsTheSame(oldConcert: Concert,
                    newConcert: Concert) = oldConcert == newConcert
        }
    }
}

Java

@Dao
public interface ConcertDao {
    // The Integer type parameter tells Room to use a PositionalDataSource
    // object, with position-based loading under the hood.
    @Query("SELECT * FROM concerts ORDER BY date DESC")
    DataSource.Factory<Integer, Concert> concertsByDate();
}

public class ConcertViewModel extends ViewModel {
    private ConcertDao concertDao;
    public final LiveData<PagedList<Concert>> concertList;

    public ConcertViewModel(ConcertDao concertDao) {
        this.concertDao = concertDao;
        concertList = new LivePagedListBuilder<>(
            concertDao.concertsByDate(), /* page size */ 50).build();
    }
}

public class ConcertActivity extends AppCompatActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ConcertViewModel viewModel =
                new ViewModelProvider(this).get(ConcertViewModel.class);
        RecyclerView recyclerView = findViewById(R.id.concert_list);
        ConcertAdapter adapter = new ConcertAdapter();
        viewModel.concertList.observe(this, adapter::submitList);
        recyclerView.setAdapter(adapter);
    }
}

public class ConcertAdapter
        extends PagedListAdapter<Concert, ConcertViewHolder> {
    protected ConcertAdapter() {
        super(DIFF_CALLBACK);
    }

    @Override
    public void onBindViewHolder(@NonNull ConcertViewHolder holder,
            int position) {
        Concert concert = getItem(position);
        if (concert != null) {
            holder.bindTo(concert);
        } else {
            // Null defines a placeholder item - PagedListAdapter automatically
            // invalidates this row when the actual object is loaded from the
            // database.
            holder.clear();
        }
    }

    private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK =
            new DiffUtil.ItemCallback<Concert>() {
        // Concert details may have changed if reloaded from the database,
        // but ID is fixed.
        @Override
        public boolean areItemsTheSame(Concert oldConcert, Concert newConcert) {
            return oldConcert.getId() == newConcert.getId();
        }

        @Override
        public boolean areContentsTheSame(Concert oldConcert,
                Concert newConcert) {
            return oldConcert.equals(newConcert);
        }
    };
}

RxJava2 का इस्तेमाल करके, पेज किए गए डेटा पर नज़र रखना

अगर आपको RxJava2 के बजाय LiveData, इसके बजाय यह काम किया जा सकता है कोई Observable या Flowable ऑब्जेक्ट बनाएं:

Kotlin

class ConcertViewModel(concertDao: ConcertDao) : ViewModel() {
    val concertList: Observable<PagedList<Concert>> =
            concertDao.concertsByDate().toObservable(pageSize = 50)
}

Java

public class ConcertViewModel extends ViewModel {
    private ConcertDao concertDao;
    public final Observable<PagedList<Concert>> concertList;

    public ConcertViewModel(ConcertDao concertDao) {
        this.concertDao = concertDao;

        concertList = new RxPagedListBuilder<>(
                concertDao.concertsByDate(), /* page size */ 50)
                        .buildObservable();
    }
}

इसके बाद, डेटा देखना शुरू और बंद किया जा सकता है. इसके लिए, यहां दिए गए कोड का इस्तेमाल किया जा सकता है snippet:

Kotlin

class ConcertActivity : AppCompatActivity() {
    private val adapter = ConcertAdapter()

    // Use the 'by viewModels()' Kotlin property delegate
    // from the activity-ktx artifact
    private val viewModel: ConcertViewModel by viewModels()

    private val disposable = CompositeDisposable()

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val recyclerView = findViewById(R.id.concert_list)
        recyclerView.setAdapter(adapter)
    }

    override fun onStart() {
        super.onStart()
        disposable.add(viewModel.concertList
                .subscribe(adapter::submitList)))
    }

    override fun onStop() {
        super.onStop()
        disposable.clear()
    }
}

Java

public class ConcertActivity extends AppCompatActivity {
    private ConcertAdapter adapter = new ConcertAdapter();
    private ConcertViewModel viewModel;

    private CompositeDisposable disposable = new CompositeDisposable();

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        RecyclerView recyclerView = findViewById(R.id.concert_list);

        viewModel = new ViewModelProvider(this).get(ConcertViewModel.class);
        recyclerView.setAdapter(adapter);
    }

    @Override
    protected void onStart() {
        super.onStart();
        disposable.add(viewModel.concertList
                .subscribe(adapter.submitList(flowableList)
        ));
    }

    @Override
    protected void onStop() {
        super.onStop();
        disposable.clear();
    }
}

ConcertDao और ConcertAdapter का कोड RxJava2 पर आधारित समाधान, जो एक LiveData पर आधारित समाधान.

सुझाव या राय दें

इन संसाधनों की मदद से, हमारे साथ अपने सुझाव, शिकायत या राय शेयर करें:

समस्या को ट्रैक करने वाला टूल
समस्याओं की शिकायत करें, ताकि हम गड़बड़ियां ठीक कर सकें.

अन्य संसाधन

पेजिंग लाइब्रेरी के बारे में ज़्यादा जानने के लिए, इन संसाधनों को देखें.

सैंपल

कोड लैब

वीडियो