بگذارید همین اول کار با یه مثال شروع کنیم. فرض کنید خبرنامه ای وجود دارد که شما با ثبت نام در اون , خبر ها رو از طریق ایمیل دریافت میکنید. به محض اینکه خبر جدیدی شد , از طریق ایمیل اون رو دریافت میکنید. اگر اینترنت شما در اون لحظه وصل نباشه , به محض اینکه وصل شد خبر رو دریافت میکنید و خبر از بین نمیرود. این داستان LiveData در اندروید است.
وقتی نیاز داشته باشید که به محض تغییر در یک دیتا(خبر) که شاید توی یک دیتابیس ذخیره شده باشه یا حتی متغیر ,عکس العملی انجام بشه مثلا Ui اپدیت بشه از LiveData استفاده میکنیم. LiveData یک کلاس observable است یعنی اطلاعاتی رو نگه میداره که بقیه (مثلا یک اکتیویتی) ازش استفاده میکنه یا به اصطلاح میتونند اون دیتا رو مشاهده کنند. چیز هایی که از دیتا استفاده میکنند(فرگمنت یا اکتیویتی) observer میگن.
یکی از فواید اینکه از lifecycle , مشاهده کننده اگاهه اینه که اگر به هر دلیلی فعال نبود ( شاید اندروید برای اینکه فضا ازاد کنه اونو به اصطلاح بکشه) برنامه شما از کار نمی افته. اگه فعال بود که هیچ اگه در حالت resume یا stop هم بود وقتی فعال شد اخرین اپدیت رو دریافت میکنه و الکی برنامه خراب نمیشه.
از این به بعد از کلمه مشاهده کننده به جای اکتیویتی یا فرگمنت یا حتی سرویسی که از اطلاعات LiveData استفاده میکند , استفاده میکنم.
LiveData یه مزیت مهم داره و اون هم اینه که از lifecycle مشاهده کننده اگاهه. یعنی میفهمه که مشاهده کننده فعاله یا غیر فعال - مثلا اکتیویتی هایی توی back stack هستند غیر فعال هستند و کاربر به صورت مستقیم نمیتونه اونو ببینه. حالا این به چه دردی میخوره؟
برگردیم به مثال . LiveData مثل خبرنامه است . کسانی که میخواهند از خبر های خبرنامه استفاده کنند باید در اون عضو بشن - اکتیویتی یا فرگمنت هایی که میخوان از دیتای LiveData استفاده کنند باید در اون عضو بشن.
اگر هنگام ارسال خبر , کاربر انلاین نباشد خبر از بین نمیرود و به محض اتصال خبر برای او ارسال میشود- به محض اینکه دیتا تغییر کرد LiveData تغییرات را برای مشاهده کننده ها( فرگمنت یا اکتیویتی) ارسال میکند و اگر اونها در وضعیت فعال نبودند , به محض فعال شدن اخرین update را دریافت میکنند.(یه فرق کوچیک با مثالمون داره و اون هم اینه که اخرین اپدیت رو دریافت میکنه نه همه خبر هایی که در زمان غیر فعال بودن ارسال شده).
مراحل کار با LiveData:
ساخت شی LiveData:
در برنامه های واقعی LiveData ها معمولا با ViewModel استفاده میشوند که مربوط به بحث ما نیست. این کد رو از داکیومنت های اندرووید اوردم ولی اگه با ViewModel ها اشنایی ندارید بهش نگاه نکنید:)
public class NameViewModel extends ViewModel { // Create a LiveData with a String private MutableLiveData<String> currentName; public MutableLiveData<String> getCurrentName() { if (currentName == null) { currentName = new MutableLiveData<String>(); } return currentName; } // Rest of the ViewModel... }
**همونطور که دربالا میبینید , ما LiveData ای از string ها ساختیم. مثل اینه که به خبرنامه بگیم فقط خبر های ورزشی رو برام ارسال کن.
ساخت شی Observer:
برای اینکه بتونیم توی خبرنامه عضو بشیم اول باید توی سایتشون ثبت نام کنیم و تنظیم کنیم که چه جور خبر هایی رو دریافت کنیم --> اول باید شی ای از جنس Observer بسازیم و با استفاده از متدonCanged که override میشود مشخص میکنیم که وقتی دیتای LiveData تغییر کرد چه کاری انجام بده. متد onCreate "مشاهده کننده" جای مناسبی برای این کاره.
در نهایت باید شی LiveData روبا استفاده از متد observe به مشاهده کننده وصل کنیم و توی اون عضو بشیم. متد observe دو تا پارامتر میگیره:
public class NameActivity extends AppCompatActivity { private NameViewModel model; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Other code to setup the activity... // Get the ViewModel. model = new ViewModelProvider(this).get(NameViewModel.class); // Create the observer which updates the UI. final Observer<String> nameObserver = new Observer<String>() { @Override public void d(@Nullable final String newName) { // Update the UI, in this case, a TextView. nameTextView.setText(newName); } }; // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer. model.getCurrentName().observe(this, nameObserver); } }
از این به بعد هر وقت دیتای LiveData تغییر کنه, متد d اجرا میشه.
دقت کنید که به Observer هم گفتیم فقط string هارو دریافت کن.
حالا سوال اصلی اینه که چطور دیتای LiveData تغییر میکنه؟؟؟؟
خود کلاس LiveData امکانات اپدیت کردن دیتاش رو نداره ولی کلاس MutableLiveData که قبلا ازش استفاده کردیم دو تا متد مناسب داره:setValue و postValue. هر جا از برنامه میتونید از اینا استفاده کنید . مثلا بر اساس کار هایی که کاربر انجام میده.
button.setListener(new Listener() { @Override public void (View v) { String anotherName = "John Doe" model.getCurrentName().setValue(anotherName); } });
از اینجا داکیومنت هاش رو بخونید(منطقا با قندشکن)
این مقاله هم شاید مفید. ولی حتما سورس کد اخر مقاله رو ببینید.