سبد خرید

آموزش استفاده از RxJava در اندروید

آموزش استفاده از RxJava در اندروید

RxJava یکی از کتابخونه های خیلی کاربردی و مفید اندروید هستش و برای هر برنامه نویسی اندروردی که میخواد توی سطوح بالا کار کنه یادگیری اون خیلی مهمه.

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

اول اینکه Rx مخفف کلمه ReactiveX به معنی برنامه نویسی واکنشی هستش.

برنامه نویسی واکنشی یعنی برنامه نویسی غیرهمزمانی که مبتی بر رخداد (Event) هستش.

بزارید یک مثال بزنم.

مثال : فرض کنید که ما توی اپلیکیشن خودمون داریم یکسری محصولات رو میفروشیم (مثل دیجیکالا و …)، توی این اپلیکیشن ما سبد خرید داریم.

با هربار اصلاح سبد خرید (افزایش یا حذف محصول) ما باید سبد خرید رو آپدیت کنیم و به کاربر نشون بدیم که چند تا محصول توی سبد خرید داره.

برای اینکار باید چیکار کنیم؟ به صورت دستی هربار که بخوایم بروزرسانی کنیم باید به دستی درخواست رو به سرور بفرستیم تا آخرین وضعیت رو دریافت کنیم.

بیاید مثال رو یکم سختترش کنیم، فرض کنید که این سبد خرید رو هم توی چندین صفحه مثل صفحه اصلی، پروفایل کاربر، صفحه جزئیات محصول هم داریم که میخوایم به کاربر نشون بدیم.

چه اتفاقی میافته؟! توی تمامی این صفحات مدام باید درخواست رو دستی ارسال کنیم و به محض دریافت اطلاعات، اطلاعات رو بروزسانی کنیم.

ولی خب دیگه واقعا خیلی وقته که این روش کدنویسی کنار گذاشته شده و اصلا اصولی نیست ازشون استفاده کنیم.

RxJava چه کمکی به ما میکنه؟

آرایکس جاوا به ما کمک میکنه بدون اینکه موارد مختلف رو مدام به صورت دستی کنترل کنیم، بروزرسانی ها (و ده ها قابلیت دیگه) که مد نظرمون هست به صورت خودکار اتفاق بیافتن.

آرایکس علاوه بر اینها خیلی راحت میتونه تردها رو هم برامون کنترل کنه.

برای انجام کارهای بزرگ و کوچیک میتونیم از تردها استفاده کنیم تا باعث فریز شدن (هَنگ کردن) اپلیکیشن نشه.

RxAndroid چیه؟

زمانی که ما داریم کارهای مختلفی رو با آرایکس انجام میدیم روی ترد پسزمینه (Background Thread) انجام میده.

ولی اگر بخوایم رابط کاربری رو تغییر بدیم و نتیجه رو به کاربر نشون بدیم قطعا نیاز به ترد اصلی (Main/UI Thread) داریم که آرایکس اندروید این ترد رو در اختیار ما قرار میده.

پس به کمک RxAndroid ما میتونیم از ترد اصلی استفاده کنیم و اطلاعاتی که توسط RxJava دریافت میکنیم رو داخل رابط کاربری خودمون آپدیت کنیم.

Schedulers ها

RxJava تردها رو توسط Schedulers مورد استفاده قرار میده.

Scheduler انواع مختلفی داره که توسط اونا میتونیم مدیریت بهتری روی ترد پسزمینه داشته باشیم.

  • IO : از این مورد اکثرا زمانی استفاده میشه که بخوایم اطلاعات مختلفی (از سرور، دیتابیس، فایل یا …) دریافت، ارسال یا ذخیره سازی کنیم.
  • Single : از این مورد اکثرا زمانی استفاده میشه که بخوایم یکسری کارها را پست سر هم و به ترتیب انجام بدیم.
  • NewThread : از این مورد اکثرا زمانی استفاده میشه که بخوایم بلافاصله بعد از انجام کاری، یک ترد جدیدی ساخته شود.
  • Computation : از این مورد اکثرا زمانی استفاده میشه که بخوایم عملیات سنگین پردازشی روی CPU مثل پردازش فایل های Bitmap و … انجام بدیم.
  • Trampoline : از این مورد اکثرا زمانی استفاده میشه که قصد داریم کارها به صورت FIFO (First In First Out) انجام بدیم.
  • MainThread : از این مورد اکثرا زمانی استفاده میشه که بخوایم به ترد اصلی دسترسی داشته باشیم و روی رابط کاربری تغییراتی رو ایجاد کنیم.

RxJava چطور کار میکنه؟

  • RxJava اطلاعات رو در قالب Observable و Observer ارسال و دریافت میکنه.
  • Observable و Observer ها توسط Subscription بهم متصل میشن.
  • اطلاعات ارسال شده رو قبل از دریافت میتونیم توسط Operator های مختلف آرایکس تغییراتی رو ایجاد کنیم.
  • توسط Schedulers هم میتونیم مشخص کنیم که عملیات مورد نظر روی کدوم یکی از تردها باید اجرا بشه.

Observable و Observer یعنی چی؟

  • Observable : وظیفه ارسال اطلاعات رو برعهده داره.
  • Observer : وظیفه دریافت اطلاعات ارسال شده توسط Observable رو برعهده داره.

نحوه پیاده سازی (خلاصه)

  1. اول باید یک Observable بسازیم تا بتونیم اطلاعات رو ارسال کنیم.
  2. توسط Operator ها میتونیم اطلاعات رو قبل از دریافت تغییر بدیم. (اختیاری)
  3. در مرحله بعد توسط Schedulers ترد مورد نظر رو مشخص میکنیم.
  4. درنهایت باید یک Subscribe ایجاد کنیم که بتونیم اطلاعات را داخل Observer دریافت کنیم.

انواع Operator ها

  • Create : اپراتورهای مربوط به ساختن Observable .
  • Transforming : اپراتورهای مربوط به تبدیل اطلاعات ارسال شده.
  • Filtering : اپراتورهای مربوط به فیلتر کردن اطلاعات ارسال شده.
  • Combining : اپراتورهای مربوط به ترکیب کردن اطلاعات ارسال شده.
  • Error Handling : اپراتورهای مربوط به مدیریت کردن خطاها.
  • Conditional and Boolean : اپراتورهای مربوط به دستورات شرطی.
  • Mathematical : اپراتورهای مربوط به انجام عملیات ریاضی.
  • Utility :اپراتورهایی که در دسته بندی بالا نیستند در این دسته قرار میگیرند.

اضافه کردن Rx در اندروید

برای اضافه کردن RxJava و RxAndroid باید کدهای زیر رو به فایل گردل پروژه اضافه کنی

implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxjava:3.1.4'

یک مثال ساده

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

به کد زیر خوب و با دقت توجه کن.

Observable.just(2,4,7,8,9,6,3)
          .subscribeOn(Schedulers.io())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe {Log.e(Constants.TAG, it.toString())}

خروجی کد بالا رو میتونید ببینید

2022-06-23 19:56:52.106 6384-6384/academy.nouri.rx E/RxTestLogs: 2
2022-06-23 19:56:52.106 6384-6384/academy.nouri.rx E/RxTestLogs: 4
2022-06-23 19:56:52.106 6384-6384/academy.nouri.rx E/RxTestLogs: 7
2022-06-23 19:56:52.106 6384-6384/academy.nouri.rx E/RxTestLogs: 8
2022-06-23 19:56:52.106 6384-6384/academy.nouri.rx E/RxTestLogs: 9
2022-06-23 19:56:52.106 6384-6384/academy.nouri.rx E/RxTestLogs: 6
2022-06-23 19:56:52.106 6384-6384/academy.nouri.rx E/RxTestLogs: 3

در مثال بالا just جز یکی از اپراتورهای مربوط به create بحساب میاد که توسط اون ما یک observable جدیدی رو میسازیم.

subscribeOn وظیفه مشخص کردن thread (نخ) رو برعهده داره و به کمک observeOn هم thread UI (نخ اصلی) که مربوط به اندروید میشه رو مشخص میکنیم.

درنهایت توسط subscribe اطلاعات ارسال شده رو دریافت میکنیم و ازشون استفاده میکنیم.

نکته
داخل subscribe میتونیم از observer استفاده کنیم که دسترسی بیشتری برای دریافت اطلاعات در اختیار ما قرار میده.

استفاده کردن از Observer

توی RxJava ما میتونیم وضعیت های مختلف دریافت اطلاعات رو با جزئیات بیشتری مدیریت کنیم.

به کد زیر توجه کن

Observable.just(2,4,7,8,9,6,3)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(object : Observer<String> {
    override fun onSubscribe(d: Disposable) {
        
    }

    override fun onNext(t: String) {
        Log.e(Constants.TAG, t.toString()
    }

    override fun onError(e: Throwable) {
        Log.e(Constants.TAG, "${e.message}")
    }

    override fun onComplete() {
        Log.e(Constants.TAG, "onComplete called")
    }
})

اگر خوب به کد بالا توجه کنی توی subscribe چهار وضعیت مختلف داریم.

  • onSubscribe : توی این متد میتونیم Disposable رو ست کنیم (این موضوع خیلی خیلی مهمه که توی مقاله های بعدی آموزش میدم)
  • onNext : توی این متد هم میتونیم اطلاعات رو دریافت کنیم.
  • onError : اگر با اروری روبرو بشیم توی این متد میتونیم ارور رو دریافت کنیم.
  • onComplete : زمانی که اطلاعات کامل دریافت بشن، این متد صدا زده میشه.
دیدگاه‌ها ۲