خانه » آموزش » اندروید » Rx java چیست؟ بخش اول

Rx java چیست؟ بخش اول

RxJava کتابخانه ایست برای برنامه نویسی بصورت Reactive در جاوا. خود Reactive Programing چیه؟ Reactive Programing روش برنامه نویسی بر اساس جریان داده و تغییرات روی آن بر اساس یک واقعه یا Event است. نمی دونم چقدر با Event و یا Reactive programing آشنایی دارید اما اگر بخوام به زبان ساده بگم Event  این است که یک واقعه رخ می دهد و بعضی کلاس ها و آبجکت ها نسبت به آن واقعه حساسند و متوجه آن می شوند. فرض کنید بابای خونه نسبت به روشن کردن کولر ( ایونت روشن شدن کولر) حساسند و هروقت اتفاق میافتد به محض مطلع شدن عکس العمل مناسب را نشان می دهند! البته این یک شوخی بود اما واقعیت قضیه همین است. در ادامه موضوع رو بیشتر باز می کنم.

RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.

خیلی خوب، گفتم که  برای برنامه نویسی بصورت Reactive در جاوا باید از RxJava استفاده کنیم. یک کامینوتی به نام ReactiveX است که تقریباً برای تمامی  زبان های برنامه نویسی مطرح، کتابخانه داده تا بتوان در آنها از امکانات Reactive استفاده کرد. مثلاً RxKotlin ،RxDart ،RxScala ،RxPHP و…. شاید بپرسید پس RxAndroid چیه؟ آیا اون هم پیاده سازی Reactive در اندرویده؟ اینجا باید بگم خیر!  RxAndroid جای گزین RxJava برای اندروید نیست. بلکه افزونه ای است متشکل از مجموعه ای از ابزار های Rx برای اندروید برای RxJava . یعنی ما در اندروید از RxAndroid به تنهایی نمی تونیم استفاده کنیم و باید در کنارش حتماً RxJava باشه. فکر می کنم در جلسات بعدی که میریم سراع مثال این مسائل این دو وابستگی را در کنار هم در Gradle مشاهده خواهید کرد.

پیش نویس این مقاله رو بیش از دو سال پیش شروع کردم. موقعی که هنوز استفاده از RxJava و RxAndroid خیلی باب نشده بود.  منتهی لازم دیدم که هرچه زود تر به این مبحث بپردازم و تا  سریعتر بتونم وارد مباحث معماری بشم  که خیلی بکارمون میاد و کمکمون می کنه. احتمالاً RxJava رو بتونم در دو یا سه جلسه تمومش کنم و امیدوارم براتون مفید باشه.

از تعاریف که بگذریم می رسیم به منطق و مفهوم کار: به نظر خود بنده Reactive Programming پیاده سازی Observer pattern در سطح برنامه نویسی است. همانطور که در ادامه مشاهده خواهید کرد، یکی از مفاهیمی که بسیارمورد استفاده در Reactive هست مفهومی به نام Observer یا نظاره گر است. پس لازم است که ببینیم این دیزاین پترن دقیقاً چی می خواد بگوید.

Observer pattern

داستان اینطوریه که کلاً سه تا مفهوم داریم. یکسری موضوع یا Subject داریم که حالت یا State خاص دارند و یک تعدادی نظاره گر یا Observer هستند که به تغییر State این Subject ها علاقه مند هستند. پس خود را برای تغیرات حالت موضوع مورد نظر مهیا می کنند و در هر تغییر حالت، این تغییر با مکانیزمی به آنها اطلاع داده شود.

در این مثال ما پدر نسبت به روشن شدن کولر حساس است و تا کولر روشن می شود آن را خاموش می کند. از طرفی روشن شدن کولر برای مادر یا فرزند اهمیتی ندارد. همینطور بوی سوختن غذا فقط برای مادر مهم است و بعد از شنیدن آن به سرعت خودش و به آشپزخانه می رساند، در صورتی که برای پدر و فرزند معنی خاصی ندارد و اصلا متوجهش نیستند. ( البته مثال خیلی انتزاعی است). RxJava هم به همین صورت است. یعنی اتفاقات و event ها بر اساس وارد شدن و یا تغییر اطلاعات فعال می شوند و یک تعدادی کلاس به آنها واکنش نشان می دهند.

حالا که پترن Observer را برسی کردیم می خواهیم مفاهیم متناظر آن در RxJava را ببینیم.

Obsrevables یا Subjects

آبجکت هایی هستند که data را نگه می دارند و برای مشاهده گرها قابل مشاهده هستند. ( موضوع –  مثل کولر در مثال ما ، البته با این تفاوت که قرار است داده ای همراه خود داشته باشند. در مثال کولر داده و state بصورت boolean بود.) و می گویند که جریان دیتا در کدام مسیر شروع می شوند (ObserveOn) و نتیجه کجا می رود. (SubscribeOn) متد های یاد شده در پرانتز را بعداً در مثال خواهید دید. فقط همین قدر بدانید که می توان مشخص کرد که مسیر شروع و پایان در کجا باشد که در جلسه بعد به آن می پردازیم. فقط یادتان باشد، ما برای سادگی در مقاله از این پس آنها را فقط با نام Observable ( به معنی قابل مشاهده) صدا می کنیم.

Observer یا Subscriber

آبجک هایی هستند که خود را بر روی Subject ها ثبت نام می کند و وقتی داده ای اضافه یا تغییر پیدا می کند آنها مطلع می شوند. ( نظاره گر – مثل پدر و فرزند و مادر در مثال.) به این نوع ابجکت ها Subscriber یا Observer می گوییم. ( به معنی نظاره گر یا مشترک.)  مراحل ارتباط بین Subscriber و Observable بدین شرح است.

  1. Subscriber برای یک Observable ثبت نام می کند. (Subscribe می کند.)
  2. داده بعدی در متد OnNext( برای اولین بار هم همین متد استفاده می شود.) وارد Observable می شود و Subscriber هم از آن مطلع می شود. ( جهت فلش را به معنی مطلع شدن در نظر بگیرید.)
  3. در نهایت جریان داده یا تمام می شود یا به خطا بر می خورد که در هردوصورت Subsriber از آن مطلع می شود.

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

انواع Observable ها:

RxJava انواع مختلفی برای Observable  در نظر گرفته که به کمک این تنوع می توانیم برای انواع مختلف داده، استفاده های مختلف و مناسبی از هرکدام داشته باشیم. برای برسی Observable ها ، Subscriber های آن را نیز برسی خواهیم کرد.

Observable

معمولی ترین نوع Subscriber یا Observer خود Observable است. دیتا می تواند در آن اضافه شود. می تواند به خطا بخورد یا اینکه تمام شود. در مثال زیر یک Observable با جنس داده String  داریم .  با استفاده از emitter که در اختیارمان قرار می دهد می توانیم داده اضافه کنیم ( ( )onNext ) و یا جریان داده را تمام یا در صورت نیاز با خطا پایان دهیم که در مثال زیر بعد از اضافه کردن چهار رشته String پایان می یابد و در صورتی که به هردلیل نتواند این چهار داده را تولید کند به خطا می خورد. ( فرض کنید به  یک رشته String هاردکد شده، قرار است از فایل متون را بخواند و در آن صورت احتمال خطا دور از ذهن نخواهد بود.)

برای استفاده از آن یک Observer از جنس زیر لازم داریم:

و برای اتصال این دو به هم کافیت:

و متد های Observer بعد از هر اتفاق درون Observable صدا زده می شند. یعنی اول onSubscribe صدا زده می شود، سپس بعد از هر خط emittter.onNext(“…”) در Observable، متد onNext(String string) در Observer صدا زده می شود و بعد از emitter.onComplete(); در Observable، متد public void onComplete() در Observer صدا زده می شود. همینطور متد خطا. اگر کدهای بالا را اجرا کنید نتیجه را در لاگ خواهید دید.

Flowable

کاملاً شبیه Observable است با این تفاوت که استراتژی های فشار برای اطلاع رسانی به Subscriber را مدیریت می کند که به آن Back pressure گفته می شود. یعنی اینکه به محض اینکه بروز شد برای subscriber مستقیم نرود و مثلا فرض کنید حجم زیادی از داده درحال جریان است. اگر همه را بصورت ورودی به نظاره گر پپاس دهیم ممکن است نتواند پردازش کند و یا داده از دست برود یا برنامه از کار بیافتد. برای همین می توانیم بخشی را مانند آب پشت سَد نگهداریم و سپس روانه کنیم. این کم کردن میزان فشار انتقال داده، باعث می شود تا حد ممکن دیتا از دست نرود و همگی پردازش شوند. مثلا در مثال پایین از استراتژی بافرکردن استفاده کردیم که روش های دیگری هم دارد که در جلسات بعدی به آنها می پردازیم.

اما نظاره گر مورد نیاز بسیار شبیه به Observer است با این تفاوت که نامش Subscriber است و باید در onSubscribe متد  s.request(x) را صدا بزنیم که می گوید چه تعداد ورودی قابل قبول است. اگر جای x عدد ۲ بگذارید فقط دوتا از ورودی هایمان را قبول می کند. اما متدهای دگرش دقیقاً شبیه Observer است.

برای اتصال:

Single

observable ای است که با یک مقدار error یا success به اتمام می رسد.

Observer مورد نیاز برای آن به شرح ذیل است:

Maybe

observerbale ای است که “با” یا “بی” مقداری پایان می یابد یا اینکه به error خاتمه می یابد .

Observer مورد نیاز برای آن به شرح ذیل است:

Completable

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

Observer مورد نیاز برای آن به شرح ذیل است:

در خاتمه این جلسه دو نکته را یاد آوری می کنم:

  • روش های دیگری نیز برای ساخت Observable و Observer وجود دارند که برسی خواهیم کرد. پس با دیدن روش های دیگر هول نشوید!
  • توجه داشته باشید که برای هریک از موارد یاد شده مثال های کاربردی زیادی دارم که به مرور و در جلسات بعدی بصورت موردی عنوان می کنم. شما چی به ذهنتون می رسه؟ به نظر کدام یک مناسب چه کاری هستند؟ روی این موارد حسابی فکر کنید. 😉
آموزش برنامه نویسی اندروید

درباره مهدی تاجیک

مهندس نرم افزار و مدیر پروژه. از سال 82 برنامه نویسی رو بصورت جدی شروع کردم و از سال 90 برنامه نویسی اندروید می کنم. علاقه زیادی به یادگرفتن و یاد دادن دارم.

۱۳ دیدگاه

  1. با سلام و وقت بخیر
    خیلی خیلی ممنون از آموزش فوق العادتون
    در نهایت سادگی ولی عالی
    منتظر ادامه آموزشتون هستیم

  2. سلام وقت بخیر
    ممنون از اموزش مفیدتون. امیدوارم هر چه زودتر بخش بعدی ان اماده شود.
    یک سوال، زمانی که مثلا از Single استفاده میکنیم، observer ان باید حتما به صورت SingleObserver تعریف شود؟

    • سلام خواهش می کنم. خوشحالم براتون مفید بوده. متاسفانه خیلی کم وقت می کنم که مطلب جدید بگذارم. ولی انشاء الله به زودی پارت دوم رو می نویسم.
      بله برای گوش دادن به Observable از جنس single باید Observer هم از جنس Single باشه. یعنی SingleObserver

  3. سلام روزتون بخير ، خيلي خيلي خوبتوضيح ميدي مهندس ، دستت درد نكنه.

  4. سلام وقتتون بخیر.
    خیلی ممنون بابت اموزش خوبتون. یه سوالی در قسمت Flowable دارم ، اینکه چطور ورودی هارو بافرشده به نظاره گر میفرسته. مثلا اگر s.request(2) باشه دقیقا چه اتفاقی می افته؟ گفتید فقط دوتا از ورودی هارو قبول میکنه. بقیه ورودی ها چی میشه؟

  5. سلام میشه یه مثال از کاربرد rx java بگید ( که برای چه کاری تا حالا استفاده شده )
    مثلا میشه وقتی ما یه مقدار boolean داخل شرد پرفرنس داریم و مقدار این boolean از هر کجا تغییر کرد ما متوجه بشیم؟

    • سلام. در آموزش بعدی که در حال نگارش هستم حتماً چند مثال کاربردی خواهیم داشت. در مورد چک کردن یک متغیر در SharedPref یا هر جای دیگر، باید تغییر آن را خودمان اطلاع دهیم و سپس Observer آن را می فهمد. بخاطر شما حتماً یک مثال SharedPref ای قرار خواهم داد.

  6. سلام واقعا خيلي خوب توضيح ميديد دمتون گرم

  7. ممنون بابت مثال ها . عالی بود 🙂

دیدگاهتان را ثبت کنید

آدرس ایمیل شما منتشر نخواهد شدعلامتدارها لازمند *

*

bigtheme