Ali Shobeyri
Ali Shobeyri
خواندن ۴ دقیقه·۵ سال پیش

ارتباط با سرور در اندروید - Coroutines + Retrofit

تا الان چند مقاله در مورد Coroutines در ویرگول گذاشتم ، اما این مقاله بدون شک مهم‌ترین و اصلی‌ترین و کاربردی‎ترین مقاله ای هست که در مورد Coroutines خواهم گذاشت ، از ورژن 2.6 به بعد در Retrofit امکان اتصال اون به Coroutines برای ما وجود داره و ما در این مقاله می‌خوایم این دو رو به هم وصل کنیم .

قبل از خواندن این مقاله این مقالات رو بخونید :

  1. پیاده سازی Coroutines در Android و Kotlin (مقدماتی و ساده)
  2. معماری Coroutines در Android و Kotlin (نگاه جزئی تر)
  3. عملیات Join و Cancel و Yield در Coroutines (برای این مقاله اختیاری است و لازم نیست)

4. تشخیص Exception ها در Coroutines

صورت مساله

یک ریکوئست که لیستی از آیتم ها رو گرفته و به ما برگردونه

لوازم حل مساله

  • Coroutines
  • Retrofit
  • LiveData

حل مساله

در ابتدا با قسمت‌های راحت ترِ کار شروع می‌کنیم ، اول کلاس Model خودمون رو درست می‌کنیم :

https://gist.github.com/sasssass/b1773fac5cb49ca1e059936d7a559bdb

بعد از اون نیاز داریم Interface وب سرویس هامون رو ایجاد کنیم ، در این مرحله یک تفاوت با روش کلاسیک وجود داره ، چون قراره اون وب سرویس درون یک Coroutine اجرا بشه پس باید نوع تابع ما suspend باشه :

https://gist.github.com/sasssass/7cf3e8895935be5ceb68b184dac7e391


تا اینجایِ کار چیز خاصی نگفتیم ، الان نوبت فایل apiCall هست که درونش قراره چند تابع که کلِ کار رو برای ما هندل می‌کنند رو قرار بدیم ، ما در Kotlin این امکان رو داریم که یک تابع رو به عنوان ورودی تابع دیگه بدیم ، در اینجا هم قراره تابعی که سرویس مورد نظر رو اجرا می‌کنه رو به عنوان ورودی تابع‌های دیگه قرار بدیم ، یکی دیگه از ورودی‌هامون یک callBack به اسم RemoteErrorEmitter خواهد بود که باید Activity یا جایی که قراره رکوئست اجرا بشه ازش Implement بشه (در مثال ما Activity خواهد بود) :

https://gist.github.com/sasssass/0e2846a7c4021d416f81bf8bb0b1cbf8

در مورد ورودی‌ها توضیح دادم ، اما در مورد عملیات درونِ تابع : ما در یک try و catch کار رو انجام می‌دیم ، در قسمت try برمیداریم یک Coroutine رو اجرا می‌کنیم (به حالت تایمری که در این مقاله توضیح دادم) و تابع responseFunction رو اجرا کرده و مجموعه رو به عنوان خروجی برمی‌گردونیم ، در صورتی که مشکلی بود و خطایی رخ داد وارد catch می‌شیم و بسته به نوعِ خطا type خاصی از ErrorType رو درون emitter (که گفتم مثلا Activity یا ... رو ازش Implement می‌کنید) پاس می‌دیم ، دقت کنید که برای خطا اومدیم Thread رو به Main تغییر دادیم ، اما کار تموم نشده ، ما باید خروجی رو به صورت یک LiveData پاس بدیم که در Activity اون رو Observe کنیم (به این مقاله مراجع کنید) ، در Coroutine یک Builder مخصوص این کار وجود داره ، ما برای فراخونی اصلی از تابعی به اسم apiCall استفاده می‌کنیم که درونش privateApiCall استفاده میشه :

https://gist.github.com/sasssass/33eb22d8bb94f24726b8fb7bc2e9219b

در این کد با استفاده از Builder مخصوص یک LiveData از مدل پاس داده میشه ، اگه دقت کنید ما تابع responseFunction رو به صورت {} پاس دادیم که syntax قضیه است و نکته خاصی نداره ، تابع emit هم برای ما اون تابع suspend ای رو که داشتیم (privateApiCall) فراخونی کرده و Value مورد نظر رو ازش می‌گیره و انتشار میده . زیبا بود نه ؟ حالا دیگه کار راحت شده و فقط مونده قسمت فراخونی و قسمت RemoteErrorEmitter که در موردش در بالاتر صحبت کرده بودیم :

https://gist.github.com/sasssass/5b4b481ce62bd6da8acb632f5ca8d869

و برای فراخونی :

https://gist.github.com/sasssass/4c58d6211e6ecd1eaf6c50f78003bfcb

کاری که اینجا کرده شده اینه که apiCall رو صدا می‌زنیم و درونش تابع مورد نظر از webService رو پاس می‌دیم ، خروجی یک LiveData خواهد بود که اونو باید observe کنیم (یعنی هر وقت مقدارش رسید عملیات درون observe اجرا میشه ، که این observe کردن یک ورودی برای lifeCycle می‌خواد که همون Activity رو می‌دیم (لایف سایکلِ اکتیویتی پاس داده میشه در واقع) و یک Observer که عملیات دریافت رو مدیریت کنه ، ورودی داخل Observer که it هست از جنس MutableList<Post> هستش . کلاس RetrofitBuilder هم که مثل قبلا هست و چیز خاصی نداره و اونو تو خودِ لینکِ گیت ببینید .

لینکِ گیتِ این مقاله :

https://gitlab.com/drflakelorenzgerman/coroutine-with-retrofit

من رو در لینکدین و اینستاگرام دنبال کنید ???

اگه دوست داشتید می‌تونید به صفحه Spotify بنده هم برید و موسیقی های منو گوش بدید ???



coroutinesکاتلینkotlinاندرویدandroid
برنامه نویس اندروید - https://www.linkedin.com/in/iryebohs/
شاید از این پست‌ها خوشتان بیاید