آموزش اندروید-فصل ۲۷-۸: Retrofit چیست و چطور کار می‌کند

مقدمه

در قسمت‌های قبلی این فصل، درباره موضوعات متوعی بحث کردیم. در این مطلب آخرین بخش مطالب مربوط به اتصال برنامه اندروید به سرور را با هم مرور می‌کنیم و در بخش (یا بخش‌های آینده) یک برنامه واقعی می‌نویسیم و از همه چیزهایی که تا به حال یاد گرفته‌اید استفاده خواهیم کرد.

در این بخش می‌خواهم شما را با Retrofit آشنا کنم. طبق تعریفی که خود پدیدآورندگان Retrofit کرده‌اند:

یک کلاینت REST نوع-امن جاوا و اندروید

است. از حاشیه‌نوشت‌های جاوا برای توصیف درخواست‌های HTTP و جانگهدارهای پارامترهای URL و … استفاده می‌شود. همچنین می‌توان از آن برای آپلود فایل و بدنه درخواست چندپاره (Multipart request body) استفاده کرد.

نکته: رتروفیت (Retrofit) نسخه ۲ کاملاً متفاوت با نسخه‌های ماقبل است. در این نوشته ما فقط از رتروفیت نسخه ۲ استفاده می‌کنیم و به نسخه‌های ماقبل آن کاری نداریم. اگر احیاناً آموزشی را از اینترنت می‌گیرید، حتماً حواستان به نسخه Retrofit هم باشد.

نصب Retrofit

برای نصب Retrofit کافی است خط‌های زیر را به build.gradle ماژول app اضافه کنید:

compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'

خط اول Retrofit نسخه ۲٫۱٫۰ را به پروژه اضافه می‌کند و خط دوم مبدل gson این کتابخانه را به پروژه اضافه می‌کند. اگر می‌خواهید از مبدل‌های دیگر استفاده کنید یا به جای JSON از XML استفاده کنید، می‌توانید مبدل دلخواه خود را از میان مبدل‌های زیر انتخاب کنید:

 مبدل  کتابخانه
 Gson  com.squareup.retrofit2:converter-gson:2.1.0
 Jackson  com.squareup.retrofit2:converter-jackson:2.1.0
 Moshi  com.squareup.retrofit2:converter-moshi:2.1.0
 Protobuf  com.squareup.retrofit2:converter-protobuf:2.1.0
 Wire  com.squareup.retrofit2:converter-wire:2.1.0
 XML  com.squareup.retrofit2:converter-simplexml:2.1.0

در ادامه فرض می‌کنیم که سرور ما برای تبادل اطلاعات از JSON استفاده می‌کند و ما هم برای تبدیل JSON به جاوا و برعکس از مبدل Gson استفاده خواهیم کرد.

ساخت کلاس‌های مدل

بعد از این که Retrifit را به پروژه اضافه کردیم، نوبت آن است کلاس‌های مرتبط با اشیاء جاوا را بسازیم. ویژگی‌های این کلاس‌های معمولاً یک تناظر یک به یک دارند با عناصر نام/مقدار در JSON.

مثلاً فرض کنید سرور در پاسخ به دریافت اطلاعات محصولات یک JSON به شکل زیر برای برنامه می‌فرستد:

{
  "name" : "TOP SALE PRODUCTS",
  "products" : [
    {
      "name" : "TABLET",
      "price" : "123456"
    },
    {
      "name" : "MOBILE",
      "price" : "123456"
    }
  ]
}

همانطور که احتمالاً حدس می‌زنید ما حداقل به دو کلاس جاوا نیاز داریم: یکی برای Product و دیگری برای خود پاسخ دریافتی.

این کلاس‌های جاوا را می‌سازیم:

public class Product {
    public String name;
    public long price;

    // Constructor and getters and setters omitted
}

و

public class Category {
    public String name;
    public List<Product> products;

    // Constructor and getters and setters omitted
}

نکته: همیشه JSON ها به این سادگی نیستند و نیز ممکن است در طول توسعه برنامه مدام تغییر کنند. همزمان نگه‌داشتن کلاس‌های مدل و JSON ممکن است فرایندی سخت و گاهی اوقات منشا بروز خطا باشد. برای ساختن کلاس‌های مدل از روی JSON ابزارهای خودکاری وجود دارند که یکی از آن‌ها jsonschema2pojo است:

jsonschema2pojo-preview

 

با کلیک کردن بر روی Preview می‌توانید یک پیش‌نمایش از کلاس‌های ایجاد شده را ببینید:

jsonschema2pojo-preview-final

کلاس‌های ساخته شده توسط این برنامه به شکل زیر هستند:

package ir.smartlab.model;

import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

@Generated("org.jsonschema2pojo")
public class Category {

	@SerializedName("name")
	@Expose
	private String name;

	@SerializedName("products")
	@Expose
	private List<Product> products = new ArrayList<Product>();

	/**
	*
	* @return
	* The name
	*/
	public String getName() {
		return name;
	}

	/**
	*
	* @param name
	* The name
	*/
	public void setName(String name) {
		this.name = name;
	}

	/**
	*
	* @return
	* The products
	*/
	public List<Product> getProducts() {
		return products;
	}

	/**
	*
	* @param products
	* The products
	*/
	public void setProducts(List<Product> products) {
		this.products = products;
	}

}

و

package ir.smartlab.model;

import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

@Generated("org.jsonschema2pojo")
public class Product {

	@SerializedName("name")
	@Expose
	private String name;

	@SerializedName("price")
	@Expose
	private String price;

	/**
	*
	* @return
	* The name
	*/
	public String getName() {
		return name;
	}

	/**
	*
	* @param name
	* The name
	*/
	public void setName(String name) {
		this.name = name;
	}

	/**
	*
	* @return
	* The price
	*/
	public String getPrice() {
		return price;
	}

	/**
	*
	* @param price
	* The price
	*/
	public void setPrice(String price) {
		this.price = price;
	}

}

حالا که کلاس‌های جاوا را هم ساختیم، نوبت این است که برویم سراغ رتروفیت!

ساخت Service Generator برای Retrofit

برای این که بتوانیم با Retrofit کار کنیم باید یک نمونه از روی آن بسازیم. برای راحتی کار کل فرایند ساخت یک نمونه از Retrofit یک کلاس می‌سازیم به نام ServiceGenerator:

public class ServiceGenerator {
    // ۱
    public static final String API_BASE_URL =
        "http://your.api-base.url";

    // ۲
    private static OkHttpClient httpClient =
        new OkHttpClient.Builder().build();

    // ۳
    private static Retrofit.Builder builder =
            new Retrofit.Builder()
                    .baseUrl(API_BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create());

    // ۴
    public static <S> S createService(Class<S> serviceClass) {
        Retrofit retrofit = builder.client(httpClient).build();
        return retrofit.create(serviceClass);
    }
}

توضیحات:

۱- نشانی سروری که قرار است برنامه ما با آن تبادل اطلاعات کند. برای مثال اگر بخواهیم از سرویس گیت‌هاب استفاده کنیم این آدرس به شکل زیر خواهد بود:

https://api.github.com/

۲- Retrofit برای برقراری ارتباط اینترنتی از OkHttp استفاده می‌کند و نیاز به یک OkHttpClient دارد.

۳- یک نمونه از کلاس Retrofit.Builder می‌سازیم که بعد با استفاده از بتوانیم یک نمونه از کلاس Retrofit بسازیم.

۴- تابع createService می‌تواند برای هر کلاینتی که کلاسش را به عنوان پارامتر گرفته باشد یک نمونه از کلاس Retrofit بسازد. در ادامه از این متد استفاده خواهیم کرد.

ساخت Client برای سرویس

حالا نوبت آن است که با استفاده از Retrofit اعلام کنیم که سرور جه API یی در اختیار ما قرار می‌دهد. این کار تقریباً حیاتی‌ترین قسمت کار با Retrofit است. فرض کنید سرویس دهنده ما قرار است سرویسی برای گرفتن کل محصولات در یک دسته‌بندی یا Category خاص و سرویس گرفتن جزئیات اطلاعات یک محصول را به ما بدهد. ما در Clientی که می‌سازیم باید این دو سرویس را به طور کامل برای Retrofit تعریف کنیم:

public interface StoreClient {  

    @GET("/store/{category}")
    Call<Category> categoryProducts(@Path("category") String category);

    @GET("/store/products/{product-id}")
    Call<Product> productDetails(@Path("product-id") long productId);
}

توضیحات:

ما دو سرویس تعریف کردیم: categoryProducts که اسم یک Category را می‌گیرد و لیست همه محصولات آن دسته‌بندی را به ما می‌دهد و productDetails که Id یا شناسه یک محصول را می‌گیرد و جزئیات آن را به ما می‌دهد. همانطور که می‌بینید قبل تعریف هر سرویس با یک حاشیه‌نوشت یا annotation ما اطلاعات بیشتری به Retrofit می‌دهیم. اولین آن‌ها نوع متد HTTP است. که در این مثال ما هر دو سرویس ما از نوع GET هستند که برای گرفتن اطلاعات تعریف شده است. در پرانتز مقابل آدرس این سرویس را مشخص کرده‌ایم. برای مثال در سرویس categoryProducts آدرس می‌شود API_BASE_URL/store/category_name. اگر دقت کنید در آدرس category را در میان {} قرار داده‌ایم. این یعنی مقدار category در لیست پارامترهای تابع داده شده است.

اگر به لیست پارامترهای سرویس categoryProducts دقت کنید می‌بینید که با حاشیه‌نوشت @Path مشخص کرده‌ایم که مقداری که به این تابع فرستاده می‌شود در آدرس سرویس به جای {category} خواهد آمد.

همه اینها به زبان ساده‌تر این است که اگر برای مثال نام category یا دسته‌بندی new باشد، آدرس سرویس می‌شود:

http://your.api-base.url/store/new

و جوابی که سرور به ما می‌دهد یک JSON است که با کمک مبدل GSON تبدیل می‌شود به یک شیء جاوا از نوع Category.

سرویس گرفتن جزئیات یک محصول هم به همین شکل است. URL این سرویس به شکل زیر است:

http://your.api-base.url/store/products/1234

که ۱۲۳۴ شناسه یا Id محصول است. سرور در جواب به ما JSONی می‌دهد که با کمک مبدل GSON به یک شیء جاوا از نوع Product تبدیل می‌شود.

فراخوانی سرویس‌ها با Retrofit

حالا همه چیز برای انجام فراخوانی و گرفتن جواب از سرور مهیا است. در کد زیر با استفاده از کلاس ServiceGenerator که پیش از این نوشتیم، این سرویس‌ها را فراخوانی می‌کنیم:

StoreClient client = ServiceGenerator.createService(StoreClient.class);

// Get Category Products
Call<Category> categoryCall = client.categoryProducts("new");
Category category = categoryCall.execute().body();

// Get a Product's details
Call<Product> productCall = client.productDetails(1234);
Product product = productCall.execute().body();

به همین سادگی!

به این فکر کنید که اگر کتابخانه‌هایی مانند Okio و OkHttp و Retrofit و GSON نبودند چقدر این کار پیچیده‌تر می‌شد! از همین جا از خالقین این کتابخانه‌ها که حاصل کار خود را به صورت رایگان و کدباز در اختیار ما گذاشتند تشکر می‌کنم!

حالا کمی از امکانات Retrofit را با هم مرور کنیم.

ارسال اشیا به سرور با Retrofit

ارسال اشیا به سمت سرور با استفاده از Retrofit بسیار ساده است. کافی است شیء مورد نظر را بسازید و با متد POST به سمت سرور بفرستید. فرض کنید کاربر بتواند برای یک محصول نظر بدهد. در این حالت از کلاس Comment یک شی می‌سازیم و با استفاده از Retrofit به سرور می‌فرستیم.

کلاس Comment ممکن است چیزی شبیه این باشد:

public class Comment {
    private String userId;
    private String commentText;
    private Date dateTime;
    private long productId;

    // Cstrs and getters and setters omitted...
}

برای ارسال این نظر به سرور یک متد جدید به StoreService اضافه می‌کنیم:

public interface StoreService {
    // Other services ...

    @POST("/store/comments/new")
    Call<Task> createComment(@Body Comment comment);
}

حالا هر زمان که کاربر برای یک محصول نظر می‌دهد با فراخوانی این سرویس آن را به سرور ارسال می‌کنیم!

پارامترهای درخواست یا Query Parameters

همیشه اطلاعات ارسالی به سمت سرور داده‌های اصلی برنامه نیستند. مثلاً در سرویس categoryProducts اگر تعداد محصولات خیلی زیاد باشد ممکن است خطاهای زیادی رخ بدهد، چه در سمت سرور و چه در سمت کلاینت. یا این که تبادل اطلاعات بسیار کند می‌شود. کاربر که قرار نیست همه محصولات را یک دفعه از سرور بگیرد. بنابراین ما باید اطلاعات را صفحه به صفحه به سمت کلاینت بفرستیم. مثلاً در هر صفحه ۱۰ یا ۲۰ محصول را بفرستیم. برای این کار در کنار اطلاعاتی که ممکن است به سمت سرور بفرستیم، داده‌هایی مانند شماره صفحه یا نحوه مرتب‌کردن اطلاعات یا بازه زمانی و اطلاعاتی از این قبیل را هم به همراه درخواست می‌فرستیم. به این داده‌ها کوئری (Query) گفته می‌شود.

فرض کنید ما برای دریافت محصولات در یک دسته‌بندی خاص می‌خواهیم شماره صفحه را هم به سرور ارسال کنیم. در این حالت متد سرویس categoryProducts به شکل زیر تغییر می‌کند:

public interface StoreService {
    // Other services ...

    @GET("/store/{category}")
    Call<Category> categoryProducts(
        @Path("category") String category,
        @Query("page") long page);
}

حالا اگر بخواهیم شیوه مرتب کردن محصولات دریافتی از سرور را هم مشخص کنیم، یک کوئری جدید به این سرویس اضافه می‌کنیم به نام sort:

public interface StoreService {
    // Other services ...

    @GET("/store/{category}")
    Call<Category> categoryProducts(
        @Path("category") String category,
        @Query("page") long page,
        @Query("sort") String sort);
}

و به همین ترتیب می‌توانیم هر تعداد از این کوئری‌ها به سرویس اضافه کنیم.

پارامترهای درخواست اختیاری یا Optional Query Parameters

در مثال قبلی فرض کنید حالتی پیش می‌آید که همزمان نمی‌خواهیم هر دو کوئری را همزمان به سرور بفرستیم. مثلاً می‌خواهیم کوئری صفحه یا page را بفرستیم اما مرتب‌سازی یا sort را نفرستیم. اگر بخواهیم برای کل ترکیب‌های ممکن یک سرویس ایجاد کنیم فرایندی سخت، پیچیده و زمان‌بر است و ممکن است باعث بروز خطا گردد.

برای حل این مشکل Retrofit اجازه می‌دهد که اگر نمی‌خواهیم یک کوئری را به سرور بفرستیم، به جای مقدار null به سرویس بفرستیم. بنابراین فراخوانی سرویس categoryProducts‌ به شکل زیر می‌شود:

storeService.categoryProducts("new", 1L, null);

همانطور که می‌بینید در این فراخوانی برای کوئری sort مقدار null فرستادیم. Retrofit کوئری‌هایی که مقدار آن‌ها null باشد را نادیده می‌گیرد و آن‌ها را به همراه درخواست به سرور نمی‌فرستند.

 پارامترهای درخواست همنام

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

برای این کار باید در تعریف سرویس تغییر بدهیم و پارامتر کوئری را از نوع لیست تعریف کنیم:

public interface StoreService {
    // Other services ...

    @GET("/store/{category}")
    Call<Category> categoryProducts(
        @Path("category") String category,
        @Query("page") long page,
        @Query("sort") List<String> sort);
}

حالا زمان فراخوانی این سرویس به شکل زیر عمل می‌کنیم:

List<String> sort = new ArrayList<String>();
sort.add("name");
sort.add("date");
storeService.categoryProducts("new", 1L, sort);

در این حالت URL ارسالی به سرور شبیه URL زیر خواهد شد:

http://your.api-base.url/store/category/new?sort=name&sort=date

همانطور که می‌بینید دو مقدار برای sort به سمت سرور ارسال می‌شود.

درخواست‌های همزمان و ناهمزمان در Retrofit

رتروفیت هم مانند OkHttp می‌تواند درخواست‌ها را به صورت همزمان (Synchronous) یا ناهمزمان (Asynchronous) اجرا کند.

نکته: در اندروید‌های ۴ به بالا، اتصال به شبکه در UI اصلی برنامه موجب بروز خطای NetworkOnMainThreadException می‌شود. بنابراین فراخوانی‌های همزمان را باید یا در سرویس‌های اندروید اجرا کرد یا در AsyncTask.

در Retrofit 2 تفاوتی در تعریف متدهای همزمان و ناهمزمان نیست و فقط در زمان فراخوانی با هم تغییر دارند.

فراخوانی همزمان:

فرض کنید می‌خواهیم سرویس categoryProducts را به صورت همزمان اجرا یا فراخوانی کنیم:

StoreService storeService = ServiceGenerator.createService(StoreService.class);
Call<Category> call = storeService.categoryProducts("new", null, null);
Category category = call.execute().body();

فراخوانی ناهمزمان:

اگر همین فراخوانی بالا را بخواهیم به صورت ناهمزمان فراخوانی کنیم به شکل زیر عمل می‌کنیم:

StoreService storeService = ServiceGenerator.createService(StoreService.class);
Call<Category> call = storeService.categoryProducts("new", null, null);
call.enqueue(new Callback<Category>() {
    @Override
    public void onResponse(Call<Category> call, Response<Category> response) {
        if (response.isSuccessful()) {
            // products available
            Category category= response.body(); 
        } else {
            // error response, no access to resource?
        }
    }

    @Override
    public void onFailure(Call<Category> call, Throwable t) {
        // something went completely south (like no internet connection)
        Log.d("Error", t.getMessage());
    }
}

همانطور که می‌بینید تفاوت اصلی در متدی است که صدا می‌زنیم. در حالت همزمان از متد execute و در حالت ناهمزمان از متد enqueue استفاده می‌کنیم.

Retrofit مباحث بسیار زیادتری دارد که فراتر از سطح این نوشته است و در حال حاضر به آن‌ها نیازی نداریم. در بخش‌های بعدی به سراغ احراز هویت (Authentication و Authorization) و لاگین و لاگ‌اوت کردن در برنامه‌های اندروید خواهیم رفت.

41 فکر می‌کنند “آموزش اندروید-فصل ۲۷-۸: Retrofit چیست و چطور کار می‌کند

  1. محمود

    ۱- چرا کدهای JSON که ابتدای این مبحث آوردید، توی سایت http://www.jsonschema2pojo.org که میذاریم و Preview می‌زنیم، هیچ چی نشون نمیده؟
    ۲- چرا مقدار page را با این که از نوع long است و باید عدد باشه ولی شما به جای عدد مقدار ۱L بهش دادید؟

    پاسخ
    1. علی بهزادیان نژاد نویسنده

      ۱- در ستون سمت راست این سایت، source type را JSON انتخاب کنید.
      ۲- در جاوا نوع لیترال یا لفظی اعداد صحیح int است. اگر بخواهیم عدد صحیح ۱ به صورت long در نظر گرفته شود باید L یا l بعدش بنویسیم. در آموزش‌های جاوا لیترال‌ها را توضیح داده‌ام:
      https://smartlab.ir/آموزش-جاوا-انواع-داده‌ها-در-زبان-جاوا/

      پاسخ
  2. محمود

    با سلام
    من متوجه نشدم که ما اینجا از GSON چه استفاده ای کردیم؟
    مثلاً برای تبدیل JSON به شیء جاوا باید از متد toJson استفاده می‌کردیم ولی اینجا از این متد استفاده نشد.
    آیا نیاز به متد toJson و fromJson برای تبدیل به شیء جاوا نیست؟

    پاسخ
    1. علی بهزادیان نژاد نویسنده

      Retrofit به صورت خودکار با استفاده از GSON اطلاعات JSON دریافتی را به شیء جاوا تبدیل می‌کند. ما لازم نیست مستقیماً کاری بکنیم.

      پاسخ
  3. محمود

    ۱- در فراخوانی همزمان پارامترها از طریق متد
    categoryProducts("new", null, null);
    ارسال شدند ولی در فراخوانی ناهمزمان این متد حذف شده؟ پس ما باید تو فراخوانی ناهمزمان چطوری پارامترها رو بدیم؟
    ۲- در فراخوانی همزمان جواب در قالب Category category گرفته میشه ولی تو فراخوانی ناهمزمان جواب دریافت شده به چه متغیری و با چه قالبی (JSON یا کلاس جاوا) داده میشه؟

    پاسخ
    1. علی بهزادیان نژاد نویسنده

      کد رو اصلاح کردم. ممنون که یادآوری کردید و شرمنده بابت این همه تاخیر 🙁

      پاسخ
  4. محمود

    موقع ساختن Service Generator برای Retrofit پیام خطا میاد روی کلمات static با این عبارت:
    Inner classes can not have static declarations
    علتش چیه؟

    پاسخ
  5. علیرضا

    برای فرستادن و گرفتن اطلاعات یکسری برنامه php هم باید نوشته بشه و داخل سرور قرار بگیره. این کد ها به چه صورتی باید باشند؟ توی خیلی از آموزشها قسمت برنامه نویسی جاوا برای رتروفیت توضیح داده شده اما قسمت کدهای php رو نمی نویسند. میشه همین اموزش رو کد های php مربوط بهش رو هم اضافه کنید؟ با اینکه php رو تا حدودی بلدم اما نمیتونم توی ذهنم ارتباط بین اون قسمت های اینترفیس رتروفیت که نوشتید با کد های سمت سرور بفهمم.

    پاسخ
    1. علی بهزادیان نژاد نویسنده

      انشالله در ادامه مطالب نمونه برنامه سمت سرور رو هم می‌نویسیم با هم. البته من علاقه‌ای به PHP ندارم و با ASP می‌نویسم 🙂

      پاسخ
      1. حیدری

        سلام استاد
        کدهای سمت سرور رو هنوز توی سایت نذاشتین یا من پیداش نمی کنم ؟
        اگر سورس ها رو می شد کامل دانلود کرد خیلی خوب می شد

        پاسخ
  6. Ali Zendehdel

    سلام استاد.
    خسته نباشید
    برای تبدیل یه جیسون ساده مثل زیر باید چه کلاس هایی داشته باشیم و برای دستور GET استفاده کرد.
    و سوال دوم اینکه چجوری میشه اطلاعات دریافتی از Object رو تو کلاس User ذخیره کنیم؟

    نمونه جیسون
    {
    “user”: {
    “id”: 150,
    “name”: “test name”,
    “email”: “example@gmail.com”,
    “mobile”: “09360398006”,
    “type”: 1
    }
    }

    پاسخ
    1. علی بهزادیان نژاد نویسنده

      دقیقا متوجه سوال نشدم. در بخش ۴ و ۵ و همین مطلب مفصل درباره جی‌سان نوشتم. مطالعه کنید و اگر جواب نگرفتید سوالتون رو واضح‌تر بپرسید

      پاسخ
  7. مهدی

    ممنون از آموزش خوبتون
    لطفا میکنید در مورد Annotation های مثل :
    @Body
    @Field
    @FormUrlEncoded
    و سایر مواردی که زیاد دیدم دارن استفاده میکنن توضیحاتی بدهید

    پاسخ
    1. علی بهزادیان نژاد نویسنده

      @Body به Retrofit می‌گوید که این پارامتر را در body درخواست قرار دهد.
      اگر از @FormUrlEncoded برای درخواست استفاده کنید باید با @Field کلیه فیلدها را مشخص کنید تا رتروفیت آن‌ها را به رشته‌های متنی تبدیل و سپس کل درخواست را به فرمت Form URL انکد کند.

      مثال از مستندات خود retrofit:

      @FormUrlEncoded
      @POST(“/”)
      Call example(
      @Field(“name”) String name,
      @Field(“occupation”) String occupation);

      حالا اگر این فراخوانی را با دو پارامتر “Bob Smith”, “President” اجرا کنید، بدنه درخواست این شکلی خواهد شد:
      name=Bob+Smith&occupation=President

      پاسخ
  8. مهدی

    سلام
    من متوجه تفاوت این کتابخانه با okhttp نشدم
    آیا اصلا اینا با هم تفاوت یا شباهتی دارن؟
    و اینکه کدومشون بهتره؟

    پاسخ
    1. علی بهزادیان نژاد نویسنده

      شرکت اسکوئر برای برقراری ارتباط اینترنتی سه کتابخانه دارد:
      Okio و OkHttp و Retrofit
      – از Okio برای ارتباط شبکه‌ای استفاده می‌شود.
      – کتابخانه OkHttp ارتباط اینترنتی (Http) را برقرار می‌کند.
      – Reftrofit به طور خاص برای صدا زدن و پردازش پاسخ‌های REST ساخته شده است. در هسته کتابخانه Retrofit از OkHttp استفاده شده است.

      پاسخ
    1. علی بهزادیان نژاد نویسنده

      POST برای ارسال اطلاعاته ولی در اغلب موارد در پاسخ، سرور داده‌هایی را برای برنامه ارسال می‌کند که برنامه ممکن است به آن‌ها احتیاج داشته باشد.

      پاسخ
  9. مسعود معيني

    سلام آقای بهزادیان نژاد
    اول میخواستم تشکر کنم از وبسایت مفیدتون و مطالب ارزشمندی که داخلش میزارید.
    راستش در مبحث Retrofit یک سوال داشتم که هر چه در سایت های خارجی یا Doc های خود Retrofit گشتم چیزی به دست نیاوردم. در آموزش شما و همه آموزش های دیگه گفته شده که اگر بخوایم به صورت داینامیک قسمت آخر یک URL رو تغییر بدیم چه کار باید بکنیم اما اگر قسمت وسط یک لینک رو بخوایم تغییر بدیم چی کار باید بکنیم؟ در این حالت اندروید استودیو اجازه استفاده از PATH@ رو نمیده و میگه باید از QUERY@ استفاده کنید . اگر میشه نحوه اجرای دستور GET برای این لینک رو در صورت اینکه بخوایم city name رو به صورت داینامیک تغییر بدیم توضیح بدیم. با تشکر

    api.openweathermap.org/data/2.5/weather?q={city name}&APPID=5shj56656dfg5e5r5d

    پاسخ
    1. علی بهزادیان نژاد نویسنده

      برای تغییر دادن قسمتی از url همونطور که خودتون گفتید از Path باید استفاده کنید:

      public interface GitHubService {
      @GET(“users/{user}/repos”)
      Call<List> listRepos(@Path(“user”) String user);
      }

      اینجا رو ببینید:
      http://square.github.io/retrofit
      همون مثال اول!

      پاسخ
  10. مسعود

    سلام مهندس جان، خسته نباشید…
    بی نهایت تشکر میکنم از زحمتی که کشیدید و این حجم از مطالب رو با دقت و صبوری تهیه کردید و گذاشتید…
    واقعاً ممنونم…
    همگی محشرن…

    پاسخ
    1. علی بهزادیان نژاد نویسنده

      به نظر من رتروفیت.
      البته اگر بخواهید دقیق‌تر مقایسه کنید باید والی رو با OkHttp مقایسه کنید

      پاسخ
  11. sadeq

    درود. من از Rerofit در پروژه ام استفاده میکنم. ولی یه ارور به من میده:
    cannot access HttpUrl
    .baseUrl(Constants.BASE_URL)
    class file for okhttp3.HttpUrl not found

    با Pstman برای تست API ام استفاده کردم و ok بود. آیا این بخاطر فیلتر بودن jcenter.bintray.com هستش؟ ممنون از شما و سایت خوبتون.

    پاسخ
    1. علی بهزادیان نژاد نویسنده

      آدرس URL نهایی رو چک کنید و بعد همون URL رو با Postman تست کنید و ببینید جواب می‌گیرید یا نه.

      پاسخ
  12. ایمان

    سلام
    من یک هدر با نام X-Auth-Token در پی اچ پی ایجاد میکنم و هنگامی که توی رتروفیت لاگ کت میکنم بدون هیچ مشکلی پرینت میشه اما اگه بخوام توی یک اینترسپتور از طریق کد زیر دسترسی پیدا کنم null بر میگردونه:

    Response res = chain.procced(chain.request);
    String token = res.headers().get(“X-Auth-Token”);

    لطفا راهنمایی بفرمایید
    با تشکر

    پاسخ
  13. مهرداد

    یه موضوع ساده رو اینقدر پبچوندی که اصلا قابل فهم نیست!خود شرکت سازنده این همه کد ننوشاه برای یه موضوع که شما نوشتین!!!برای آموزش مثال ساده و خیلی سریع لازم هست نه خلاقیتی که شما دارید

    پاسخ
  14. یزدخواستی

    با سلام و تشکر در رابطه با مبحث رتروفیت سوالی دارم:یک فایل جیسونی روی هاستم دارم(person.json) که محتویات آن در هر لحظه در حال تغییر است قطعه کدی می خواستم که مثلا در هر ۱۰ ثانیه این فایل را از طریق رتروفیت get کند قطعه کدی در اینترنت پیدا کرده ام که از طریق observable محتویات پستی(https://api.chucknorris.io/jokes/random) را هر چند ثانیه یک بار می خواند و نمایش می دهد:
    https://github.com/journaldev/journaldev/tree/master/Android/AndroidRetrofitCallEveryXSecond
    من میخواهم طوری کدها رو تغییر دهم که فایل من رو بخواند:
    http://seeb-sorkh.com/rp15/13981000/person.json
    راهنمائی بفرمائید.

    پاسخ
  15. دوست

    ممنون
    مطلب خوبی بود

    اما برای کسی که تازه میخواد با رتروفیت کار کنه خیلی پیچیده و سنگینه

    بهتر نبود دو آموزش ساده و پیشرفته میگذاشتی؟

    پاسخ

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *