معرفی Android Architecture Components: LiveData

پنج شنبه ۱۳ اردیبهشت ۹۷ توسط یوسف رضا مختاری

سلام به یک مقاله دیگر از مجموعه مقالات Android Architecture Components خوش اومدید  .

اخیرا ما ViewModel را  برای فراهم کردن و نگهداری دیتا برای UI (مثل Activity و Fragment) معرفی کردیم .

اگر این مقاله را مطالعه نکردید من پیشنهاد میکنم این کار را انجام دهید .

امروز ما میخواهیم درباره LiveData صحبت کنیم که یک دارنده دیتا observable یا قابل مشاهده است که از lifecycle آگاه می باشد .

بیایید شروع کنیم.

معرفی

ما  از ViewModel مثال پست قبلی استفاده میکنیم . جایی که ما یک کلاس ViewModel با لیستی از کاربران داشتیم :

public class UsersViewModel extends ViewModel {
 
     private List<User> userList;
 
     public List<User> getUserList() {
        if (userList == null) {
             usersList = loadUsers();
         }
         return userList;
     }
 
     private List<User> loadUsers() {
         // do something to load users
     }
 }

با ViewModel لازم نیست نگران بسیاری از مشکلات باشیم , مثل پاس دادن دیتا به Activity از نو ساخته شده بعد از تغییر وضعیت و یا memory leak ناشی از عمر بیشتر نسبت به Activity .

اما بجای اینکه ما هر بار که دیتا نیاز داریم آن را دریافت کنیم بهتر است که هر زمانی چیز جدیدی وجود داشت آن را اطلاع دهد .

این بهتر نیس؟

این امکان با LiveData امکان پذیر است که یک دارنده دیتا قابل مشاهده است که از lifecycle آگاه می باشد .

بیایید ببینیم این چه مفهومی دارد:

چگونه کار می کند؟

 هنگامی که ما یک شی LiveData داریم (مثلا لیستی از کاربران) ، ما میتوانیم LifecycleOwner ( می تواند Activity یا Fragment باشد) را به عنوان observer یا ناظر به بروز رسانی دیتا اضافه کنیم  .

دقیقا مانند observer pattern یا الگو ناظر , اما با توجه به حالت های lifecycle . پس :

  • ما (به عنوان Activity یا Fragment)  در زمان تغییر دیتا به جای درخواست دیتا از ViewModel , به ما اطلاع داده خواهد شد ( بنابراین UI همیشه آپدیت می شود! )
  • این ها همه بستگی به lifecycle دارد بنابراین ما برای مشاهده تغییرات تنها اگر اکتیویتی (یا هر LifecycleOwner دیگر) در وضعیت STARTED یا RESUMED  باشد ثبت نام میکنیم و فقط پس از آن LiveData هر آیتم منتشر می شود . (بنابراین هیچ  memory leak و NullPointerExceptions به خاطر موجود نبودن view نداریم)

 

چگونه از آن استفاده کنید؟

اولا، ما نیاز داریم dependency های مناسب را به فایل app / build.gradle خود اضافه کنیم :

implementation "android.arch.lifecycle:extensions:1.0.0"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0"

حالا بیایید از  مثال قبلی (LiveData با لیستی از کاربران) استفاده کنیم :

public class UsersViewModel extends ViewModel {

    private MutableLiveData<List<User>> userLiveData = 
        new MutableLiveData<>();

    public UsersViewModel() {
         setUserListRefreshCallback(newUserList -> {
             userLiveData.postValue(newUserList);
         });
     }
 
     public LiveData<List<User>> getUserList() {
         return userLiveData;
     }
 }

اولا ما  <List<User با MutableLiveData بسته بندی میکنیم .

ما میخواهیم LiveData را فقط درون کلاس UsersViewModel تغییر دهیم و به همین دلیل یک ورژن mutable یا قابل تغییر از LiveData وجود دارد.

هر زمانی تغییراتی در داده ها (از جمله در منابع خارجی) به وجود بیاید ما میخواهیم مقدار جدید را به LiveData  ارسال کنیم .ما میتوانیم این کار را با استفاده از متد ()postValue (به طور غیر همزمان) یا ()setValue (به صورت همزمان , که باید آن را  UI thread خود اجرا کنیم) انجام دهیم.

در مرحله بعد ما میتوانیم LiveData را با یک getter به نمایش در آوریم.

پس میتوان از آن به آسانی در Activity استفاده کند .

public class UsersActivity extends AppCompatActivity {
 
     @Override
     protected void onCreate(final Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
 
         UsersViewModel usersViewModel =
             ViewModelProviders.of(this).get(UsersViewModel.class);
 
         usersViewModel.getUserList()
             .observe(this, this::showUsers);

    }
}

ما  در دریافت دیتا تفاوت میبینیم — اکنون ما خودمان را به عنوان یک ناظر به تغییرات لیست کاربران اضافه می کنیم .

ما به متد ()observe دو پارامتر را پاس می دهیم

  • اول یک LifecycleOwner (اساسا اکتیوینی ما) و به لطف LiveData می داند که چه زمانی  باید اکتیویتی را از تغییرات مطلع کند .
  • دومی یک callback یا فراخوانی با پارامتر <List<User که ما میتوانیم استفاده کنیم از متد ()showUsers .

از حالا به بعد ما نیاز نیست نگران مدیریت وضعیت های lifecycle و  ثبت نام/لغو ثبت نام  از این observable باشیم .

 

کارهای بیشتر با LiveData

ما میتوانیم با استفاده از کلاس های Architecture Components کمی با LiveData  بازی کنیم.

به عنوان مثال اگر ما بخواهیم برخی از تغییرات در LiveData قبل از قرار دادن آن در ViewModel منتشر شود ما می توانیم با استفاده از Transformations این کار را انجام دهیم:

 

()Transformations.map

اگر ما به کل Object های User نیاز نداشته باشیم ,  فقط نام آنها را بخواهیم , ما میتوانیم از تابع ()map استفاده کنیم .

LiveData<String> userNames = Transformations
    .map(userLiveData, user -> {user.name});

 

MediatorLiveData 

ما همچنین می توانیم با استفاده از MediatorLiveData  مشاهده چندگانه LiveData را با یک منبع ادغام کنید .

به عنوان مثال، اگر ما می خواهیم دیتاهایی که از دیتابیس و شبکه هستند را ادغام کنیم ، می توانیم این کار را انجام دهیم :            

LiveData<List<User>> usersFromDatabase;
LiveData<List<User>> usersFromNetwork;

MediatorLiveData<List<User>> usersLiveData = 
    new MediatorLiveData<>();

usersLiveData.addSource(usersFromDatabase, newUserList ->
    usersLiveData.setValue(value));

usersLiveData.addSource(usersFromNetwork, newUserList ->
    usersLiveData.setValue(value));

 Activity فقط میتواند شی usersLiveData را مشاهده کند و هر زمانی در هر کدام تغیییری بوجود آید مطلع می شود .

 

LiveData & Room

اگر شما  از Room در پروژه خود استفاده میکنید (و اگر اینکار را نمی کنید - چرا؟) باید بدانید که query های شما می توانند اشیاء LiveData را بازگردانند:

@Dao
public interface UserDao {

@Query("SELECT * FROM users WHERE name=:name")
     LiveData<List<User>> getUsersByName(String name);

}

query ها به صورت همزمان ساخته می شوند . (بنابراین شما نگرانی در مورد ساخت آنها روی thread مناسب ندارید) و شما observer pattern یا الگوی ناظر را به صورت رایگان  دارید.

(پس هر زمانی محتوا در دیتابیس تغییر کند، شما در مورد آن مطلع خواهید شد) .

 

امیدوارم این مطلب برای شما مفید بوده باشد.

 
 
 
 
 
 

کلیدواژه: آموزش برنامه نویسی اندروید Android Architecture Components Room اندروید معرفی LiveData

منابع: android.jlelse.eu

دیدگاه ها:
۳ هفته قبل
reply
عالی بود ممنون
۷ ساعت قبل
reply
عالی بود
ارسال دیدگاه:
برای ارسال دیگاه باید به سیستم وارد شوید و یا ثبت نام کنید. ثبت نام چند لحظه بیشتر زمان شما را نمیگیرد.