آشنایی با LiveData در برنامه نویسی اندروید

آشنایی با LiveData در برنامه نویسی اندروید
آشنایی با LiveData در برنامه نویسی اندروید

یکی از چالش هایی که در برنامه نویسی به آن برمیخوریم بروز رسانی View متناسب با تغییرات object می باشد.

فرض کنید یک دکمه Follow دارید که بعد از اینکه کاربر آن را لمس کرد رنگ و برچسب آن تغییر میکند و به تعداد Follower ها یکی اضافه می شود.

برای حل این چالش راه های مختلفی در اندروید هست:

  • چک کردن عادی یک متغیر boolean و تغییر عنوان و رنگ دکمه
  • استفاده از interface
  • استفاده از Event bus
  • استفاده از LiveData



در این مطلب قصد دارم مروری بر LiveData در برنامه نویسی اندروید داشته باشم . LiveData از مباحث مهم Android Architecture Components می باشد. LiveData میتواند تغییرات را رصد کند و تأثیر این تغییرات بر object ها را مدیریت و بروزرسانی کند. LiveData ساختاری شبیه به observable دارد با این تفاوت که از lifecycle-aware تبعیت میکند. با استفاده از LiveData دیگر نگران memory leak نباشید چون وقتی اکتیویتی در وضعیت STARTED یا RESUMED قرار بگیرد LiveData فعال است و وقتی اکتیویتی در وضعیت DESTROYED قرار بگیرد LiveData و object متناظر آن غیر فعال شده و از وقوع memoy leak جلوگیری می شود.

از LiveData در معماری MVVM نیز استفاده می شود . ViewModel پل ارتباطی بین View و Model می باشد و LiveData پل ارتباطی بین ViewModel و View می باشد که برای این کار از Observer Pattern که یکی از دیزاین پترن های معروف است استفاده میکند.

در واقع LiveData ابزاری برای ارتباط و مدیریت بهتر بین مشاهده کننده (Observer) و object یا همان Observable می باشد. به عبارت دیگر نگاه Observer به Observable می باشد تا در صورت تغییر در Observable خودش را به آن وفق دهد.

مثال بالا را در نظر بگیرید:

در این مثال یک FollowStatus داریم که شامل خصوصیت های زیر می باشد :

  • state
  • background
  • label
  • countFollowers

در واقع FollowStatus همان Observable هست که توسط Observer که همان دکمه باشد مشاهده می شود .

یک LiveData از جنس FollowStatus تعریف میکنیم و در دکمه با توجه به وضعیت فعلی و با دستور setValue مقدار FollowStatus را به LiveData پاس میدهیم.

میتوانیم از دستور postValue هم استفاده کنیم که فرق آن با setValue در این است که setValue در main Thread اتفاق می افتد ولی postValue در background Thread.

حال باید دستور observe برای LiveData فراخوانی کنیم تا در صورت تغییر , بروز رسانی وضعیت دکمه رو انجام دهد.

نمونه کد زیر را مشاهده کنید:

public class TestActivity extends AppCompatActivity 
{   
        private Button btn_follow;    
        private TextView tv_countFollowers;    
        private WebService webService;
        private MutableLiveData<FollowStatus> liv_follow = new MutableLiveData<>();
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) 
        {                                        
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_test);
                webService = callWebService();
                btn_follow = findViewById(R.id.btn_follow);
                tv_countFollowers = findViewById(R.id.tv_countFollowers);
                btn_follow.setListener(new View.Listener()
                 {
                        @Override
                        public void (View v) 
                        {
                                  boolean isFollow = webService.isFollow();
                                  int numberOfFollowers = webService.getCountFollowers();
                                  if (isFollow)  {
                                     // unfollow
                                    FollowStatus unFollowModel =
                                    getUnFollowModel(numberOfFollowers);
                                    liv_follow.setValue(unFollowModel);
                                    } else  {
                                     // follow
                                      FollowStatus followModel = getFollowModel(numberOfFollowers);
                                      liv_follow.setValue(followModel);
                                     }
                       }
          });
          setObservers();
  }
  private FollowStatus getUnFollowModel(int countFollowers) 
  {
  return new FollowStatus(false, R.drawable.ic_circle_unselect, "UnFollow", countFollowers - 1);
   }
   private FollowStatus getFollowModel(int countFollowers) 
   {
 return new FollowStatus(true, R.drawable.ic_circle_unselect, "Follow", countFollowers + 1);
   }
   private void setObservers() {
             liv_follow.observe(this, new Observer<FollowStatus>(){
                @Override
                 public void d(FollowStatus followStatus)  {
                             btn_follow.setText(followStatus.getLabel());
                              btn_follow.setBackgroundColor(followStatus.getBackground());                                                                       tv_countFollowers.setText(String.valueOf(followStatus.getCountFollowers()));
                                 }
               });
    }
    private WebService callWebService() {
              return new WebService();
       }
}




چه تفاوتی بین MutableLiveData و MediatorLiveData هست؟

کلاس LiveData جزو کلاس های پایه ای هست و معمولا برای کار با LiveData از فرزندان آن یعنی MutableLiveData و MediatorLiveData استفاده می شود.

کلاس MediatorLiveData از MutableLiveData ارث بری میکند و MutableLiveData از LiveData ارث بری میکند پس میتوانیم نتیجه بگیریم که MediatorLiveData خصوصیات MutableLiveData و LiveData را دارد.

از MutableLiveData همچون مثال بالا برای مشاهده و آپدیت ویو ... استفاده می شود.

ولی از MediatorLiveData به عنوان واسطه ای بین دو یا چند LiveData استفاده می شود و میتوان با کمک آن ، مقادیر بین دو یا چند LiveData را با یکدیگر ادغام (merge) کرد و یا مقادیر هر کدام از LiveData ها را به یک View واحد نسبت داد.

فرض بگیرید 2 فرگمنت دارید که در هر کدام یک SeekBar در حال نمایش است اگر بخواهیم مقادیر این دو SeekBar با یکدیگر هماهنگ باشد از MediatorLiveData استفاده میکنیم.

سورس کد زیر را مشاهده کنید:

https://github.com/masoudmahmoodzadeh/MediatorLiveData-Example



سایر مطالب بنده:

آشنایی با Context در اندروید

چرخه حیات به سبک Lifecycle Aware در اندروید

چرخه حیات فرگمنت ها در اندروید

چرخه حیات اکتیویتی ها در اندروید

معرفی کتاب نوسازی