آموزش Retrofit (رتروفیت)
بخش اول: ایجاد یک درخواست ساده
اگر به صفحه اصلی Retrofit مراجعه کنید، تعریف کوتاه زیر را برای آن مشاهده خواهید کرد:
اما اجازه دهید آن را کمی بهتر توضیح دهیم:
در این مطلب که اولین درس از آموزش رتروفیت میباشد، قصد دارم تا حالت کلی پیادهسازی رتروفیت و نحوهی ایجاد یک درخواست ساده را به شما آموزش دهم.
پیش نیازهای پروژه
وابستگیهای زیر را بایستی به پروژهی خود اضافه کنید.
- کتابخانه Retrofit (نیازی به تبدیل کنندهها نیست؛ فقط خود کتابخانه را اضافه کنید؛ تبدیل کنندهها را در بخشهای خود توضیح خواهم داد.)
- کتابخانه Okhttp
- کتابخانه Okio
ساخت آبجکت Retrofit
برای ساخت یک آبجکت retrofit و ارتباط آن با وبسرویس، به صورت زیر عمل میکنیم:
1 2 3 |
Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://fullkade.com/") .build(); |
همانطور که میبینید، از الگوی طراحی بیلدرها در رتروفیت استفاده شده و ما نیز از طریق آن، آبجکت رتروفیت را میسازیم؛ اما چیزی که در اینجا مهم است، متد baseUrl میباشد.
برای توضیح baseUrl، فرض کنید فایلی با نام test.php را درون پوشهای به نام app که در ریشهی هاست ما قرار دارد، ایجاد کردهایم و کدی داخل آن نوشتهایم که مقداری را چاپ کند. و حالا اگر فرض کنیم دامنهی fullkade.com را به هاست خود وصل کردهایم (البته از IP هم میتوان استفاده کرد)، آنگاه آدرس دقیق این فایل به صورت زیر خواهد بود:
حالا ما میتوانیم در baseUrl، مسیری که قرار است به ابتدای مسیرهای بعدی اضافه شود را قرار دهیم (یعنی آدرس پایه)؛ برای مثال:
و سپس در هرجایی که میخواهیم به فایلی درخواست ارسال کنیم، تنها بقیهی آدرس را مینویسیم که در ادامهی آموزش خواهید دید.
پس طبق توضیحات بالا، انتظار میرود که بتوان به صورت زیر هم baseUrl را نوشت:
ولی فراموش نکنید که در این صورت، بعدا بقیهی آدرس را باید از app به بعد بنویسیم.
ایجاد یک Interface
ابتدا اینترفیس زیر را در نظر بگیرید:
1 2 3 4 5 6 |
public interface FullKadeService { @GET("users/{user}/repos") Call<List<Repo>> listRepos(@Path("user") String user); } |
من دقیقا همین اینترفیس را از مستندات خود Retrofit کپی کردهام و چیزی که میخواهم به شما بگویم تنها ساختار نوشتن یک Interface در Retrofit میباشد.
حالا اولین چیزی که باید بدانید، این است که در Retrofit ما برای ایجاد یک درخواست، به اینترفیسها نیاز داریم؛ و روشی که ما اینترفیسها را پیاده میکنیم، به صورت بالا میباشد.
- یک نام دلخواه برای Interface انتخاب میکنیم.
- یک متدی با نام دلخواه در Interface مینویسیم. (متدهای دیگری نیز میتوانند وجود داشته باشند)
- خروجی متد را با کلاس Call اما با نوعهای مختلف میتوانیم تعریف کنیم. در این جا نوع آن را یک لیست که از کلاس Repo میباشد، تعریف کردهایم.
همچنین کلاس Repo یک کلاس اختصاصی است. - بالای متد، با استفاده از GET یا POST که مطمئنن بایستی با آنها آشنا باشید، تعیین میکنیم که اطلاعات ما با چه روشی و به چه آدرسی ارسال شود.
البته باید بدانید که این آدرس، به ادامهی همان baseUrl که در بالا گفتیم اضافه خواهد شد. - متد میتواند ورودیهایی داشته باشد؛ در اینجا Path برای قرار دادن ورودی user در آدرس URL و به جای {user} خواهد بود! اما ما میتوانیم نوع دیگر ورودیها را هم تعریف کنیم؛ مثلا یک سری پارامتر با روش GET یا POST به سرور ارسال شود که البته در مثال بالا وجود ندارد. اما در بخشهای بعدی توضیح خواهم داد.
در نهایت، از این اینترفیس قرار است در همان Retrofit ای که ساختهایم استفاده کنیم.
مثال: گرفتن محتوا به صورت رشته از وب سرویس
بالاخره وقت مثال رسید! 😀
فعلا قصد نداریم تا مدل JSON یا XML و … را از وبسرویس گرفته و آنها را به آبجکت جاوا تبدیل کنیم؛ بلکه هدفمان این است تا همان محتوای متنی گرفته شده از وب را در خروجی به کاربر نمایش دهیم.
برای شروع میتوانید فایلی در هاست خود ایجاد کنید؛ مثلا من همان فایل test.php را در پوشهی app هاست خود ایجاد میکنم و درون آن کد زیر را قرار میدهم:
1 2 3 |
<?php echo "Welcoom to FuLLKade"; |
خب همانطور که باید بدانید، با اجرای این صفحه در مرورگر، پیام Welcome to FuLLKade دریافت میشود. اما ما قصد داریم محتوای این فایل یا صفحه را با استفاده از کتابخانهی Retrofit گرفته و به کاربر نمایش دهیم.
1- برای این کار، ابتدا یک Interface با هر نامی ایجاد میکنیم؛ سپس متدی درون آن به صورت زیر پیاده میکنیم:
1 2 3 4 5 6 |
public interface StringInterface { @GET("app/test.php") Call<ResponseBody> getTest(); } |
در اینجا، خروجی را از نوع ResponseBody تعریف کردهایم؛ چرا که در ساختار رتروفیت، از آن برای گرفتن محتوای صفحه به صورت String استفاده میشود. و همچنین این کلاس، یکی از کلاسهای کتابخانهی Okhttp میباشد که در Retrofit استفاده شده است.
2- در هرجایی از برنامهی خود، مثلا در رویداد کلیک:
ابتدا یک آبجکت Retrofit ایجاد کرده و سپس Interface خود را روی آن پیاده میکنیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://fullkade.com/") .build(); StringInterface service = retrofit.create(StringInterface.class); Call<ResponseBody> result = service.getTest(); result.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { try { Toast.makeText(MainActivity.this, response.body().string(), Toast.LENGTH_LONG).show(); } catch (IOException e) { Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_LONG).show(); } } @Override public void onFailure(Call<ResponseBody> call, Throwable throwable) { Toast.makeText(MainActivity.this, throwable.getMessage(), Toast.LENGTH_LONG).show(); } }); |
در رابطه با کد بالا:
- آبجکت رتروفیت را ساخته و مقداردهی میکنیم.
- کلاس اینترفیس را داخل متد create مربوط به retrofit ارسال میکنیم؛ تا متدهای داخل اینترفیسی که ساختهایم را پیادهسازی کرده و کامل شدهی آن را به ما برگرداند.
- متدی که داخل اینترفیس نوشتهایم را اجرا میکنیم و سپس خروجی آن را در آبجکنی از جنس خروجی همان متد به نام result نگهداری میکنیم. (البته هنوز درخواست به سرور ارسال نشده است)
- از متد enqueue که برای کلاس Call میباشد، برای اجرای درخواست استفاده میکنیم.
این متد، همواره یک Callback از جنس خروجی متد گرفته و نتیجه را داخل آن به ما برمیگرداند.- رویداد onResponse: اگر عملیات با موفقیت انجام شود، این متد اجرا خواهد شد.
پارامتر call، همان result است که در اینجا نیز برگردانده میشود.
پارامتر response، پاسخ درخواست ما میباشد که از جنس کلاس Response بوده و فقط در اینجا نوع ریسپانس آن، ResponseBody میباشد. و همچنین در داخل متد، ما خروجی آن را به صورت «response.body().string()» دریافت کردهایم؛ که خطای IOException نیز ممکن است در آن رخ دهد. - رویداد onFailure: اگر عملیات با شکست مواجه شود (مثل قطع بودن اینترنت گوشی و …)، این متد اجرا خواهد شد.
پارامتر throwable، اطلاعات مربوط به خطای ایجاد شده است.
- رویداد onResponse: اگر عملیات با موفقیت انجام شود، این متد اجرا خواهد شد.
ممنون خیلی مفید بود با قدرت ادامه بدین
، اشتباه تایپی دارین چند بار reprofit استفاده کردین و یه جا هم آبجکنی.
سپاس از توجه و لطف شما. کل متن اصلاح شد. (نتیجهی تند نوشتن و از اون بدتر نخوندن چیزی که نوشتی 😀 )
موفق و پیروز باشید.