آموزش های این وب سایت به صورت رایگان در دسترس است. اطلاعات بیشتر
مشکل عدم دسترسی خریداران پیشین به برخی آموزش ها برطرف شد
بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

آموزش کامل رتروفیت

مسعود کریمی نژاد  7 سال پیش  7 سال پیش
+50 0

سلام خدمت همه ی دوستان عزیز

خب سوال اول اینکه رتروفیت کلا چیه؟ 

خیلی از ما ها برنامه هایی رو میخوایم بنویسیم که نیاز به ارتباط با سرور و رد و بدل کردن اطلاعات بین نرم افزار و سرور داره. در واقع بیشتر برنامه هایی که ما امروزه میبینیم به ارتباط با سرور نیاز دارند. خب توی این مورد خیلیا میان و کلاس هایی رو برای ارتباط با سرور آماده میکنن و در برنامشون از ائن کلاس استفاده میکنن. اما به دلیل پیچیدگی ها و مشکلاتی که این کار داره چاره ای جز استفاده از کتابخانه ها ی آماده نیست. یکی از بهترین کتابخانه هایی که امروزه تقرییبا همه ی برنامه نویس ها لاقل سعی میکنن که توی برنامشون ازش استفاده کنن لایبراری  Retrofit هست. طبق گفته ی خود سازنده های این کتابخانه (Square) این کتابخانه یک نوع امن سرویس گیرنده ی http برای اندروید و جاوا توسط square هست. (برای اطلاع کتابخانه های picasso , okhttp  هم توسط همین گروه ساخته شدن)

رتروفیت چه ویژگی هایی داره ؟

  • سرعت بالا در ارتباط با سرور
  • امنیت بیشتر ( اینو نمیدونم چرا میگن امنه اما خب همه میگن منم میگم شمام قبول کنید )
  • سهولت در استفاده (وقتی کار با این کتابخونه رو یاد بگیرید میفهمید که چقدر راحته و کارتون رو راحت میکنه) 
  • در کنار Gson که توی خود رتروفیت هست دیگ هیچ وقت کلمه ی JsonObject یا JsonArray رو در کدهاتون نخواهید دید و هیچوقت دغدغه ی پارس کردن جیسون رو نخواهید داشت.
  • ارسال درخواست های http برای وب سرویس هایی که با Rest Api‌ پیاده سازی سازی شده اند. درخواست های http مثل post , get , put , delete , ... ( برای پیاده سازی Rest Api سمت سرور میتونید یک اموزش کامل رو در androidhive ببینید

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

+4 0
بسیار عالی کار پسندیده ای کردی زکات علم نشر ان است به امید اموزش های بیشتر .. (7 سال پیش)
+2 0
من یک مدتی خیلی دنبال رتروفیت بودم و سایت های زیادی رو برای آموزشش گشتم ، به نظرم یکی از کامل ترین آموزش های مربوط به رتروفیت 2 رو میشه گفت لینک هستش ، امیدوارم بدرد همه بخوره :) (7 سال پیش)
+2 0
خیلی ممنون از آموزشتون ، میخواستم بدونم که رتروفیت کار دانلودر هم انجام میده ؟ منظورم این هستش که میشه مثلا توی پروژه مارکت استاد از رتروفیت برای دانلود عکس و فایلهای APK استفاده کرد ؟ (7 سال پیش)
+1 0
اگه بخوایم اطلاعات رو از https بگیریم چه تغییراتی ایجاد میشه؟ (7 سال پیش)
 برای این سوال 14 پاسخ وجود دارد. مشاهده پاسخ صحیح
پاسخ به سوال 
مسعود کریمی نژاد  7 سال پیش
+16 0

خب در این قسمت میخوایم رتروفیت رو پیاده سازی کنیم و اون رو تست کنیم. چند تا نکته :

  • ما توی اندروید استودیو این کار رو میکنیم
  • از جدید ترین نسخه ی retrofit که نسخه ی 2.1.0 هست استفاده میکنیم
  • هدف ارسال یک جیسون به سرور و دریافت یک جیسون از سرور است

خب بریم سر اصل مطلب. اول وابستگی های زیر رو به پروژتون اضاف کنید. 

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

خب اینا که نیازی به توضیح ندارن. 

در ابتدا ما نیاز به یک کلاس داریم که برای ما یک کلاینت رتروفیت آماده کنه تا درخواست هارو روی اون اجرا کنیم. من خودم از کلاس زیر استفاده میکنم.

 

import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
* Created by Asus on 29/10/2016.
*/

public class ApiClient {
public static final String BASE_URL="http://your_domain/.../";

private static Retrofit retrofit = null;
private static String TAG=ApiClient.class.getSimpleName();


public static Retrofit getClient() {


if (retrofit==null) {
OkHttpClient client=new OkHttpClient.Builder()
.readTimeout(20, TimeUnit.SECONDS)
.connectTimeout(20, TimeUnit.SECONDS)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}

}

این قسمت توضیح خاصی نداره فقط :

  •  BASE_URL چیه؟ این آدرس همون دایرکتوری هست که فایل های php توی اون قرار دارن. مثلا  /http://your_domain.ir/webservice .  ادامه ی url ها رو در جای دیگه بهش میدیم. در ادامه میگم
  • Timeout هارو من روی 20 ثانیه قرار میدم.

خب فرض کنید ما قراره یک همچین جیسونی رو از سرور دریافت کنیم. این جیسون رو توی این http://www.jsoneditoronline.org/  کپی کنید و اونو بررسی کنید.

 {
"error": false,
"posts": [
{
"body": "body 1",
"image_url": "url 1",
"sender": {
"last_name": "last_name 1",
"name": "name 1"
},
"title": "title 1"
},
{
"body": "body 2",
"image_url": "url 2",
"sender": {
"last_name": "last_name 2",
"name": "name 2"
},
"title": "title 2"
},
{
"body": "body 3",
"image_url": "url 3",
"sender": {
"last_name": "last_name 3",
"name": "name 3"
},
"title": "title 3"
},
{
"body": "body 4",
"image_url": "url 4",
"sender": {
"last_name": "last_name 4",
"name": "name 4"
},
"title": "title 4"
}
]
}

توی این جیسون ما میخوای یک لیستی از post ها بگیریم. هر پست دارای مشخصاتی هست مثل title, body..  . ,  و این پست یک فرستنده هم داره که با sender نشون داده شده . خب قبل از هر کاری ما باید یک کلاس مدلی طراحی کنیم که با این جیسون یه جورایی مچ باشه. خب اینجا یک نکته ای وجود داره . هر جا ما jsonObject داشتیم یعنی باید یک شی از یک کلاس داشته باشیم. این شی میتونه از کلاس String‌ یا میتونه هر کلاس مدلی باشه که خودمون درست کردیم. و هر جا jsonArray داشتیم یعنی باید یک List  یا ArrayList از یک شی داشته باشیم. که باز هم این شی میتونه هر چیزی باشه.

خب در اینجا ما به چند تا کلاس مدل نیاط داریم . عکس زیر رو نگاه کنید. 

من جیسون رو توی اون سایتی که گفتم کپی کردم تا بهتر بتونم اجزای اونو از هم تفکیک کنم. همونطور که میبینید جیسون اصلی دارای یک فیلد error و یک آرایه به اسم posts داره. هر post خودش یک title, body,image_url داره و همچنین یک sender که هر sender هم یک name,last_name داره. خب ما از داخلی ترین آبجکت شروع میکنیم. 

داخلی ترین جیسون یعنی sender‌نشان دهنده ی فرستنده ی این پست هست. من یک کلاس به اسم User درست مکنم به شکل زیر: 

 
import com.google.gson.annotations.SerializedName;

import java.io.Serializable;

/**
* Created by Masoud Karimi on 09/12/2016.
*/

public class User implements Serializable {

@SerializedName("name")
private String name;

@SerializedName("last_name")
private String lastName;

public User(String name, String lastName) {
this.name = name;
this.lastName = lastName;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

}

خب این یک کلاس هست که در واقع ما user هارو توش نگه میداریم. اما سوال اینجاست که SerializedName@ چیه ؟ ما با استفاده از این annotation به رتروفیت (در واقع به Gson )میفهمونیم که فیلدی که توی جیسون اسمش name هست رو توی این متغیر بریز و فیلدی که اسمش last_name هست رو توی فیلد lastName بریز. پس همینجا چند تا نکته  رو هم بگم :

  1. اگر فیلدتون توی جیسون قرار بود رشته باشه توی جاوا به String نیاز دارید و اگر boolean بود در جاوا هم به boolean نیاز دارید و اگر یک عدد دسیمال بود به int و عدد اعشاری هم به float یا double نیاز داریم. این نکته در مورد کلاس های مدلی هم که خودمون میسازیم صدق میکنه که در ادامه متوجه منظورم خواهید شد.
  2. نکته ی دیگه این که توابع getter و setter رو در کلاس های model خودتون ننویسید. یک کلیک راست کنید روی صفحه بعد گزینه ی Generate رو انتخاب کنید بعد بزنید روی getter and setter بعد فیلد هارو انتخاب کنید و اوکی بزنید خود اندروید استودیو تمام توابع رو به صورت استاندارد براتون میسازه.
  3. نکته ی دیگ اینکه حتما کلاس هاتون رو از Serializable  ایمپلمنت کنید. 

خب نکته ی دیگه ای نداره بریم بقیه ی کلاس ها رو بسازیم. خب حالا نیاز به یک کلاس برای ذخیره پست ها داریم. یک کلاس به اسم Post میسازیم : 

 
import java.io.Serializable;

/**
* Created by Masoud Karimi on 09/12/2016.
*/

public class Post implements Serializable {


@SerializedName("title")
private String title;

@SerializedName("body")
private String body;

@SerializedName("image_url")
private String imageUrl;

@SerializedName("sender")
private User sender;

public Post(String title, String body, String imageUrl, User sender) {
this.title = title;
this.sender = sender;
this.imageUrl = imageUrl;
this.body = body;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getBody() {
return body;
}

public void setBody(String body) {
this.body = body;
}

public String getImageUrl() {
return imageUrl;
}

public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}

public User getSender() {
return sender;
}

public void setSender(User sender) {
this.sender = sender;
}


}

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

خب حالا بریم برای اخرین کلاس مدل. این کلاس مدل در واقع بیرونی ترین جیسون مارو تشکیل میده . اگر توجه کنید در جیسون ما یک فیلد error داریم و یک آرایه به اسم posts. اول کلاس رو ببینید : 

 
import com.google.gson.annotations.SerializedName;

import java.io.Serializable;
import java.util.ArrayList;

/**
* Created by Masoud Karimi on 09/12/2016.
*/

public class PostRetrofitModel implements Serializable{

@SerializedName("error")
private boolean error;

@SerializedName("posts")
private ArrayList<Post> posts=new ArrayList<>();

public boolean isError() {
return error;
}

public void setError(boolean error) {
this.error = error;
}

public ArrayList<Post> getPosts() {
return posts;
}

public void setPosts(ArrayList<Post> posts) {
this.posts = posts;
}
}

ببینید من گفتم که این کلاس یک فیلد boolean داره که اسم سریالی اون error هست و یک فیلد دیگه داره که یک آرایه هست  از کلاس Post که خودمون ساختیم که اسم سریالی اون رو گذاشتم posts که در جیسون هم همین نام رو داره. با این کار اون آرایه ی posts در جیسون تبدیل میشه به یه آرایه از نوع Post و در این فیلد قرار میگیره. توجه کنید که اسم خوده فیلد ها با اسم سریالی اونها هیچ ربطی به هم ندارن و فقط اسم سریالی باید با اسم توی جیسون یکی باشه. تا بعدا اگر خواستید توی برنامه اسم فیلد رو تغییر بدید نیازی به تغییر جیسون خروجی وب سرویستون نداشته باشید.

حالا اگر توجه کنید کلاس PostRetrofitModel ما  ساختاری دقیقا مشابه با جیسون خروجی ما داره. 

خب توی این قسمت هم نحوه ی ساختن کلاس های مدل رو برای رتروفیت یادگرفتیم. در ادامه نحوه ی دریافت این جیسون از سرور رو یاد میگیریم. 

پاسخ به سوال 
مسعود کریمی نژاد  7 سال پیش
+5 0

کد ها خوب نمایش داده نشد. توی پاسخ بعدی قرار میدم

پاسخ به سوال 
مسعود کریمی نژاد  7 سال پیش
+11 0

قسمت سوم : ارسال درخواست به سرور و دریافت جیسونی که در قسمت قبل توضیح داده شد. 

فرض کنید جیسون ما در آدرس زیر باشه 

http://your_domain.ir/webservice/test.php?page=1

خب اون قسمت اول رو که ما در آدرس BASE_URL قرار دادیم. پس فقط به test.php نیاز داریم. یک اینترفیس به صورت زیر میسازیم : 

 public interface APIService {

@Headers({
"content-type: application/x-www-form-urlencoded"

})
@GET("test.php?page={page}")
Call<PostRetrofitModel> getPosts(@Path("page") int page);
}
 
 

یک اینترفیس به اسم APIService میسازیم و توش تمام درخواست هایی رو که میخوایم به سرور بدیم رو معرفی میکنیم. در اینجا ما قرار یک جیسون رو دریافت کنیم و اون رو به یک شی از کلاس  PostRetrofitModel تبدیل کنیم. در annotation اول هدر هایی رو که میخوایم ست میکنیم. در annotation  بعد میگیم این یک در خواست از نوع get هست   که آدرس اون رو در ادامه بهش میدیم. توی این url یک قسمتی رو با { } جدا کردم . با این کار بهش میگیم که این قسمت بعدا قراره با مقداری که ما بهش میدیم پر بشه. خب میرسیم به خوده تابع همونطور که میبینید من بهش گفتم خروجی این تابع قراره یک PostRetrofitModel باشه. همچنین یک ورودی هم داره که یک مقدار int هست و بهش میگیم این مقدار مربوط به page هست. اگر میخواید اطلاعات بیشتری در مورد نحوه ی کار با این annotation ها به دست بیارید اینجا https://square.github.io/retrofit/  رو ببینید.

خب حالا باید این تابع رو اجرا کنیم. نحوه ی صدا کردن تابع به صورت زیر است: 

 
 APIService service= ApiClient.getClient().create(APIService.class);

Call<PostRetrofitModel> call=service.getPosts(1);
call.enqueue(new Callback<PostRetrofitModel>() {
@Override
public void onResponse(Call<PostRetrofitModel> call, Response<PostRetrofitModel> response) {
PostRetrofitModel result=response.body();

// اطلاعات به درستی دریافت شدند


}

@Override
public void onFailure(Call<PostRetrofitModel> call, Throwable t) {
Log.i("TAG","failure :"+t.getLocalizedMessage());
// خطایی رخ داده است
}
});
 

خب ابتدا یک کلاینت میسازیم سپس تابع رو به شکل بالا اجرا میکینم. اگر اطلاعات به درستی دریافت بشن تابع onResponse اجرا میشه و خروجی جیسون رو میتونید به شکل بالا به صورت یک شی از کلاس PostRetrofitModel  دریافت میکنیم. و در صورتی که خطایی رخ بده مثلا اینترنت وصل نباشه یا درخواستتون اشتباه باشه یا نتونه ارتباط برقرار کنه با سرور متد onFailure  اجرا میشه. 

+1 0
با تشکر فراوان واقعا زحمت کشیدین (7 سال پیش)
+1 0
ممنون مهندس فقط یک سوال اینکه بین کتابخونه volley و retrofit کدوم بهتره ؟ (7 سال پیش)
+2 0
قطعا retrofit. من قبلا از والی استفاده کردم خیلی جاها کار نمیکرد یا خطا میداد. شنیمدم دیگ گوگل ساپورتش نمیکنه. به هر صور در حال حاضر بهترین همین رتروفیته (7 سال پیش)
+1 0
البته والی توسط گوگل ساپورت میشه و فقط اون لایبرری که توی گیت هاب که ورژن اصلی والی نبود دپریکیت شده ولی واقعا رتروفیت خیلی خوبه.خسته نباشید (7 سال پیش)
+1 0
بچه ها برنامه من موقع گذاشتن مقدار getposts کرش میکنه و هروقت برش میدارم درس میشه؟؟ (7 سال پیش)
0 0
کدوم قسمت رو منظورتونه؟ یکم دقیق تر توضیح بده (7 سال پیش)
+1 0
یه سوال: بنده با استفاده از رتروفیت ثبت نام میکنم کاربر رو، با موفقیت انجام میشه ولی میره توی onFailure و این ارورو میده End of input at line 1 column 1 path $ (7 سال پیش)
+1 0
خروجی جیسونتون مشکل داره و نمیتونه تبدیلش کنه. جیسونتون رو بررسی کنید. اگر حل نشد کلاس مدل و خروجی جیسون رو اینجا بذارید تا ببینیم مشکلش چیه (7 سال پیش)
0 0
ممنون - از converter-gson تو کدها استفاده نکردین ! بعد از اینکه خروجی جیسون دریافت شد چطوری به تبدیلش کنیم ؟ چون این کتابخانه برای تبدیل خروجی جیسون هستش (7 سال پیش)
+1 0
چرا دیگ کتابخونشو که همون اول گفتم اضافه کردیم. جیسون ها رو خوده رتروفیت به وسیله‌ی همین gson که درون خودش داره به کلاس های مدل ما تبدیل میکنه. (7 سال پیش)
0 0
یه سوال: وقتی که برنامه اجرا میشه خطای Failed to connect to /127.0.0.1:80 را نمایش میده ، دلیلش چیه؟ (7 سال پیش)
پاسخ به سوال 
مسعود کریمی نژاد  7 سال پیش
+8 0

قسمت چهارم : ارسال یک جیسون به سرور 

در این قسمت میخوایم یک نمونه از کلاس Post  رو که در قسمت های قبل توضیح دادیم مقدار دهی کنیم و اونو به جیسون تبدیل کنیم و با متد پست برای سرور ارسال کنیم. 

فرض کنید صفحه ی php که قراره ما فراخوانی کنیم به صورت زیر باشه :

http://your_domain.ir/webservice/new_post.php

اول میایم و یک تابع جدید به interface که ساخته بودیم به صورت زیر اضاف میکنیم. 

 
public interface APIService {

@Headers({
"content-type: application/x-www-form-urlencoded"

})
@GET("test.php?page={page}")
Call<PostRetrofitModel> getPosts(@Path("page") int page);
/******* NEW METHOD FOR NEW POST *******/

@Headers({
"content-type: application/x-www-form-urlencoded"
})
@FormUrlEncoded
@POST("new_post.php")
Call<MyResponseBody> newPost(@Field("data") String data);
}

خب تابع رو اسمش رو گذاشتم newPost . هدر content-type  که گذاشتم برای ارسال با متد پست معولا باید همین مقدار رو داشته باشه. همیشه برای متد های POST و PUT  باید annotation مربوط به FormUrlEncoded رو قرار بدید. بعد از اون من گفتم که این درخواست از نوع POST هست و آدرس صفحه ی php رو بهش دادم. این تابع یک ورودی رشته داره که همون جیسونی هست که قراره ما به یرای سرور ارسال کنیم. و اما کلاس MyResponseBody چیه؟ یه کلاس بنویسید به صورت ساده با مثلا چند تا فیلد که نشون بده خطایی رخ داده یا نه یا اگر خایی رخ داده متن اون خطا چیه. خلاصه متناسب با پاسخی که از سرورتون دریافت میکنید یک کلاس مدل براش بسازید. مثلا یک نمونه ساده از این کلاس رو ببینیم : 

public class MyResponseBody implements Serializable{


private boolean error;
private String message;

public boolean isError() {
return error;
}

public void setError(boolean error) {
this.error = error;
}



public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}


}

خیلی ساده یک فیل error‌ داره و یک فیلد message . شاید بپرسید چرا براشون نام سریالی انتخاب نکردم ؟ در برخی موارد نیازی نیست حتما نام سریالی برای فیلد ها انتخاب کنید اما حواستون باشه اسم فیلد ها توی جیسون باید با اسم فیلد ها توی جاوا یکی باشن. مثلا یک جیسون معتبر برای این کلاس میتونه به صورت زیر باشه : 

 {"error":true,"message":"incorrect data"}

خب حالا چطور تابع newPost رو فراخوانی کنیم. اول بیایم و یه post جدید بسازیم با یه سری اطلاعات به صورت زیر : 

 Post post=new Post("title","body","image url",new User("name","last name"));

حالا این شی رو تبدیل میکنیم به یک جیسون. به صورت زیر : 

String postJson=new Gson().toJson(post);

به همین راحتی تبدیل شد به یک جیسون که میتونید لاگش کنید و ببینیدش. 

خب حالا به صورت زیر تابع newPost رو فراخوانی میکنیم : 

APIService service= ApiClient.getClient().create(APIService.class);
Call<MyResponseBody> call=service.newPost(postJson);
call.enqueue(new retrofit2.Callback<MyResponseBody>() {
@Override
public void onResponse(Call<MyResponseBody> call, Response<MyResponseBody> response) {
MyResponseBody result=response.body();
Loger.i("TAG","error="+result.isError());
Loger.i("TAG","message="+result.getMessage());



}

@Override
public void onFailure(Call<MyResponseBody> call, Throwable t) {

Loger.i("TAG","onFailure="+ t.getLocalizedMessage());

}
});

در مورد این تابع هم که مثل مثال قبل هست توضیح دادم و نکته ی خاصی نداره. 

موفق باشید

+1 0
عزیز یه مشکل دیگه برخوردم میخوام توی هدر یه مقدار دلخواه بفرستم. مثلا به این شکل @Headers("X-Authorization: " + token) ولی اون توکن رو ایراد میگیره میگه باید استاتیک باشه. استاتیکش میکنم یه ایراد دیگه میگیره چه کنم آیا؟ (7 سال پیش)
0 0
سلام مسعود جان مشکل وب سرویس استاد چی هست ؟ من تا الان باهاش کار کردم به مشکلی نخوردم نمیدونم علت اینکه بقیه دوستان تمایل دارن با رتروفیت یا والی کار کنن چی هست اگه یک توضیحی بدید خیلی ممنون میشم (7 سال پیش)
+1 0
وب سرویس استاد که فک کنم دپریکیت شده. اگر مشکلی ندارید که از همون استفاده کنید. (7 سال پیش)
0 0
متشکرم ، با compile کردن یک کتابخونه میشه زنده ش کرد (7 سال پیش)
0 0
سلام من لاگین دارم که کاربر باید نام کاربری و رمز عبورش رو به سرور ارسال کنه و بعدش حق دسترسی هاش رو سرور بهش در یه جیسون بهش میده منتها سرور با HTTPS هستش و باید Basic Authorization براش ست بشه ، با این روش بالا رفتم ولی جواب نداد ، آیا راه حل دیگه ای داره ؟ ممنون (7 سال پیش)
پاسخ به سوال 
مسعود کریمی نژاد  7 سال پیش
+7 0

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

برای اضافه کردن هدر ها اگر مقدار هدر یک مقدار ثابت هست میتونید به صورت زیر عمل کنید : 

 
@Headers({
"content-type: application/x-www-form-urlencoded",
"authorization:"+ STATIC_HASH,

})
@FormUrlEncoded
@POST("new_post.php")
Call<MyResponseBody> newPost(@Field("data") String data);

اما اگر این هدر قرار باشه به صورت داینامیک به تابع داده بشه از روش زیر استفاده میکنیم : 

@Headers({
"content-type: application/x-www-form-urlencoded"

})
@FormUrlEncoded
@POST("new_post.php")
Call<MyResponseBody> newPost(@Header("authorization")String authorization , @Field("data") String data);

به این صورت میگیم که ورودی اول تابع رو در هدر authorization قرار بده

0 0
مسعود جان من توی قسمت دریافت جستون تو @Get کلا گیر کردم میشه یه سورس کوچولویی همراه با دریافت این جیسون و نمایشش توی یه تکست ویو.ممنون (7 سال پیش)
0 0
لینک (7 سال پیش)
+1 0
کجاش مشکل داری؟ برای گرفتن این جیسون کلاس اصلیت فقط یه فیلد از نوع arrayList داره به اسم employees که خوده این آرایه از نوع یه کلاس دیگس. یه کلاس دیگ که دو تا فیلد firstName و lastName داره که مشخصه باید از نوع رشته باشه. (7 سال پیش)
0 0
' Code' Call call = APIBaseAdapter.loadEmployees(1); (7 سال پیش)
0 0
وقتی مقدار loadEmployees رو مثلا میزارم 1 برنامه کرش میکنه. (7 سال پیش)
+1 0
بقیه ی کد هارو بذار (7 سال پیش)
+1 0
بقیه کدهاتون رو بذارید تا ببینم مشکلتون کجاست (7 سال پیش)
0 0
'final TextView txt = (TextView) findViewById(R.id.textview); APIAdapterCreator apiAdapterCreator = new APIAdapterCreator(); APIBaseAdapter mTService = apiAdapterCreator.getmTService(); Call call = APIBaseAdapter.loadEmployees(); call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { String string = response.body().String("firstName"); Log.i("Log", "String = : " + string); txt.setText(string); } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); Log.i("LOG", "error === " + t.getMessage()); } }); } }' (7 سال پیش)
0 0
اینتر فیس =پایین (7 سال پیش)
0 0
public interface APIBaseAdapter { @GET("569ce520110000fb2dce7655") static Call loadEmployees(); } (7 سال پیش)
0 0
حالا از جیسونی که بالا گذاشتم اگه میشه یکیشو توش قرار بدین بعد نمایشش بدین ببینم چجوریه؟ (7 سال پیش)
0 0
مسعود جان هر چی شما نوشتین من هم نوشتم توی کد هام فقط با این تفاوت که توی جیسونم اون چیزایی که شما نوشتین اصلا توش نیست. من گفتم حالا اگه جیشونم مشکل داشت فوقش چاپش نمیکنه ولی حالا کلا برنامه کرش میکنه. حالا مشکل از اینه؟؟؟ (7 سال پیش)
0 0
میشه کدهای php اون جیسونی که اول گزاشتین رو هم بزارین؟ (7 سال پیش)
0 0
سلام ممنون ولی از هیچ کدوم از روش های بالا نشد هدر من دقیقا به این شکله "Authorization", "Token "+ tknn ممنون میشم راهنمایی کنید (7 سال پیش)
0 0
Authorization", "Bearer "+ tknn" (7 سال پیش)
0 0
داداش این چه کاریه کردی خب؟ تو یه پاسخ میذاشتی کداتو (7 سال پیش)
0 0
دوستان این کدها اصلا قابل خوندن نیست لطفا هرکس مشکلی داره کدهاشو توی پاسخ بذاره تا بهتر بشه بررسیشون کرد. (7 سال پیش)
0 0
ببخشید گفتم تاپیک خراب نشه (7 سال پیش)
+1 0
اقای کریمی کل کدهای من دقیقا مثل کدهای شماست فقط توی قسمت "test.php?page=1" برای من اینجوری هستش "test.php" و برنامه من کرش میکنه . دلیلش چیه؟؟؟؟ (7 سال پیش)
0 0
خب کرشت رو بذار ببینیم چی میگ. فقط تو نظرات نذار لطفا (7 سال پیش)
0 0
اگر توی هدر page رو حذف کردید پس حتما باید ورودی تابع رو هم حذف کنید (7 سال پیش)
0 0
Frame is not available اینم کرش (7 سال پیش)
0 0
تا حالا ندیدم این کرشو. اگ میخوای کدارو بذار ببینم چی نوشتی (7 سال پیش)
پاسخ به سوال 
Farshad  7 سال پیش
0 0

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

public interface APIService {

@GET("api/Profiles/GetProfile?id={id}")
Call<UserProfile> getUser(@Header("Authorization")String authorization , @Path("id") String id);
}
 
 
0 0
خب هدر رو بد نوشتین . دقیقا مثل این لینک بنویسید (7 سال پیش)
0 0
اقای فرشاد میشه کد فراخوانی همین متد رو توی اکتیوتی اصلی رو قرار بدین ببینم چجوریه؟ (7 سال پیش)
0 0
خدمت شما لینک (7 سال پیش)
0 0
آقا مسعود کدو تغییر دادم به شکل بالا. الان درسته ؟؟ ولی بازم کار نمیکنه (7 سال پیش)
+1 0
فرشاد جان برا ای دی هم تو getuser میزنم 1 ولی برنامه کرش میکنه (7 سال پیش)
0 0
احتمالا مشکل اون قسمت @Path هستش باید به @Query تغییر بدید (7 سال پیش)
0 0
الان این تابع درسته مشکلتون باید از جای دیگ باشه (7 سال پیش)
پاسخ به سوال 
GhollamHosein  7 سال پیش
0 0

intrface

public interface APIService {

@Headers({
"content-type: application/x-www-form-urlencoded"

})
@GET("mysite/index.php?posts={posts}")
Call<PostRetrofitModel> getPosts(@Path("posts") int posts);
}


Mainactivity

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView txt = (TextView) findViewById(R.id.textview);
final APIService service = ApiClient.getClient().create(APIService.class);
Button btn = (Button) findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Call < PostRetrofitModel > call = service.getPosts(1);
call.enqueue(new Callback<PostRetrofitModel>() {
@Override
public void onResponse(Call<PostRetrofitModel> call, Response<PostRetrofitModel> response) {
PostRetrofitModel result = response.body();

// اطلاعات به درستی دریافت شدند


}

@Override
public void onFailure(Call<PostRetrofitModel> call, Throwable t) {
Log.i("TAG", "failure :" + t.getLocalizedMessage());
// خطایی رخ داده است
}
});
}
});

}
}

http://192.168.//.153/mysite/index.php?posts=1
0 0
اقا مسعود نمیدونم چرا کرش میکنه؟ (7 سال پیش)
0 0
آدرس بیس رو چی دادین؟ (7 سال پیش)
0 0
لینک (7 سال پیش)
0 0
((((((((http://192.168.//.153/)))) (7 سال پیش)
+1 0
این چه نوع ادرسیه ؟ (7 سال پیش)
0 0
اون پرانتز ها رو اطرافش گزاشتم که به عنوان لینک درج نشهhttp://192.168.20.153/ (7 سال پیش)
0 0
خب شما اول توی کروم تست کن ببین خروجی جیسونت درسته یا نه (7 سال پیش)
0 0
آره دقیقا همون جیسونی رو خروجی میده که توی پست دوم درج کردین.میشه یه سورس کوچیک بمن بدید تا توی اندروید استودیو کامپایل کنم ببینم کتابخونه چجوری کار میکنه؟ (7 سال پیش)
+1 0
نه متاسفانه . کدهایی که گذاشتم فکر نمیکنم ایرادی داشته باشن. اگر وقت کردم تست میکنم ببینم جواب میدن یا نه (7 سال پیش)
0 0
باشه ممنون ولی فک کنم ایراد دارن (7 سال پیش)
پاسخ به سوال 
Farshad  7 سال پیش
0 0

یک سوال دیگه

بنده یک جیسون مشابه زیر از سرور دریافت میکنم :

 {"ProfilList":[{"UserName":"far","Id":"1","Email":"a@a.com"}]}

اینو چجوری باید از مقدار بازگشتی بگیرم

+1 0
دقیقا شبیه سوال شما رو تو نظرات این قسمت لینک جواب دادم (7 سال پیش)
پاسخ به سوال 
Farshad  7 سال پیش
0 0

سلام

من با استفاده از رتروفیت با سرور ارتباط برقرار کردم و دیتا میگیرم

توی اندروید 5 و 6 و 7 اوکیه

ولی توی اندروید 4 - 4.1 - 4.2 ارور 500 میده

واقعا نمیدونم چرا این ارورو میده همه اطلاعات درست ارسال میشه

ممنون میشم راهنمایی کنید

پاسخ به سوال 
GhollamHosein  7 سال پیش
0 0

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

 

بنده میخام  این جیسون رو توی یک لیست ویو نشون بدم.

 

{

"contacts": [
{
"id": "c200",
"name": "Ravi Tamada",
"email": "ravi@gmail.com",
"address": "xx-xx-xxxx,x - street, x - country",
"gender" : "male",
"phone": {
"mobile": "+91 0000000000",
"home": "00 000000",
"office": "00 000000"
}
},
{
"id": "c201",
"name": "Johnny Depp",
"email": "johnny_depp@gmail.com",
"address": "xx-xx-xxxx,x - street, x - country",
"gender" : "male",
"phone": {
"mobile": "+91 0000000000",
"home": "00 000000",
"office": "00 000000"
}
}

 و اینکه تا وقتی که ارایه ی contacts  نیستش از این خط کد استفاده میکنم.

;(JSONObject jsonObject=jsonArray.getJSONObject(0

 و هر وقت ارایه contact  رو بهش اضافه میکنم دیگه کار نمیکنه.

 

ممنون میشم راهنمایی کنید؟

0 0
بچه ها حل شد ممنون.ووو... :) اگه کسی مشکلی داشت بگه تا براش توضیح بدم (7 سال پیش)
پاسخ به سوال 
احسان  7 سال پیش
0 0

سلام دوستان

من دارم از رتروفیت استفاده میکنم ولی گاهی اوقات به قسمت Call  که می رسه داخلش نمیره !

این هم کد من ممنون میشم  راهنمایی کنید . چند روزه دارم دنبال جواب میگردم ولی چیزی پیدا نکردم

 

Call<ListModelResponse> serviceListsModels = service.getListModels(url);

serviceListsModels.enqueue(new Callback<ListModelResponse>() { // تا اینجا برنامه اجرا میشه ولی از این خط به بعد داخل نمیشه
@Override
public void onResponse(Call<ListModelResponse> call, Response<ListModelResponse> response) {

........ Response کد های داخل ......

}
+1 0
بقیه ی کدها رو بذار . با این تیکه کد نمیشه مشکلو فهمید. جیسون رو هم بذاری خوبه (7 سال پیش)
0 0
ممنونم مشکلم حل شد ، دلیل مشکل این بود که مدلی که برای داده ها ساخته بودم توی یک جا یه مقدار متفائت بود اون رو که درست کردم مشکل حل شد و لی من یه لاگین دارم که کاربر باید نام کاربری و رمز عبورش رو به سرور ارسال کنه و بعدش حق دسترسی هاش رو سرور بهش در یه جیسون بهش میده منتها سرور با HTTPS هستش و باید Basic Authorization براش ست بشه ، با این روش بالا رفتم ولی جواب نداد ، آیا راه حل دیگه ای داره ؟ (7 سال پیش)
0 0
من با https تست نکردم حقیقتش (7 سال پیش)
0 0
بچه ها میشه یه توضیح مختصری راجع به لاگین کردن و تایید اطلاعات با رتروفیت بدید (7 سال پیش)
پاسخ به سوال 
علی زنده دل  7 سال پیش
0 0

فکر میکنم با بیلد کردن این خطوط بجای retrofit توضیح داده شده در گریدل مشکل شما برای استفاده از Https حل بشه

compile('com.squareup.retrofit2:retrofit:2.2.0') {
exclude module: 'okhttp'
}
compile 'com.squareup.okhttp3:okhttp:3.6.0'
compile 'com.squareup.retrofit2:converter-gson:2.2.0'

البته باز هم آقای کریمی نژاد عزیز در این مورد میتونن نظر قطعی رو بدن

پاسخ به سوال 
علی زنده دل  7 سال پیش
0 0

 پاسخ صحیح

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

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

نمونه ی جیسون دریافتی

{
  "user": {
"id": 14,
"name": "test name",
"email": "example@gmail.com",
"mobile": "11223344667"
}
}

کلاس User

 public class User implements Serializable {

@SerializedName("id")
private int id;
@SerializedName("name")
private String name;
@SerializedName("email")
private String email;
@SerializedName("mobile")
private String mobile;


public User(int id, String name, String email, String mobile) {
this.id = id;
this.name = name;
this.email = email;
this.mobile = mobile;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getMobile() {
return mobile;
}

public void setMobile(String mobile) {
this.mobile = mobile;
}

}

کلاس Post

public class Post implements Serializable {


@SerializedName("user")
private User user;

public User getUser() {
return user;
}

public void setUser(User user) {
this.user = user;
}


}

کلاس PostRetrofitModel

public class PostRetrofitModel implements Serializable {

@SerializedName("user")
private ArrayList<Post> user = new ArrayList<>();

public ArrayList<Post> getPosts() {
return user;
}

public void setPosts(ArrayList<Post> posts) {
this.user = posts;
}
}

کلاس APIService

public interface APIService {

@Headers({
"content-type: application/x-www-form-urlencoded"

})
@GET("login?api_key={api_key}&email={email}&password={password}")
Call<PostRetrofitModel> getPosts(@Path("api_key") String api_key,
@Path("email") String email,
@Path("password") String password );
}

این هم قطعه کد برنامه

APIService service= ApiClient.getClient().create(APIService.class);
Call<PostRetrofitModel> call = service.getPosts();
call.enqueue(new Callback<PostRetrofitModel>() {

@Override
public void onResponse(Call<PostRetrofitModel> call, retrofit2.Response<PostRetrofitModel> response) {
PostRetrofitModel result = response.body();



if (result != null) {
Log.i("LOG", result.getPosts() + "");
}



}

@Override
public void onFailure(Call<PostRetrofitModel> call, Throwable t) {
Log.i("TAG","failure :"+t.getLocalizedMessage());
// خطایی رخ داده است
}
});

ممنون میشم یه توضیحی بدین دقیقا چجوری کلاس بندی باید برای Post و PostModel داشته باشم. حدس میزنم مشکل از نحوه ی کلاس بندی برای جیسونم باشه. 

و برای ذخیره کردن اطلاعات از responde هم باید چکار کنم.

آهان ذکر این نکته هم لازمه که API سایتی که براشون کار میکنم ، چون تو ورژن های اولشه خیلی ساده طراحی شده  و فقط با GET کار میکنه.

مرسی و ممنون

+1 0
دوست من شما توی postRetrofitModel گفتید یک آرایه از user ها دریافت میکنید. اما جیسون شما یک آبجکت هست. مشکل شما عدم تطابق جیسون و کلاس مدلتون هست (7 سال پیش)
+1 0
در ضمن در کلاس مدلتون getter و setter نام درستی ندارن که بازم رتروفیت حتما خطا میده (7 سال پیش)
+1 0
الان دوباره نگاه کردم اصن کلاس Post چی میشگه اون وسط؟؟ کلا فقط جیسون رو تغییر دادید. لطفا آموزش رو دوباره مطالعه کنید. موفق باشید (7 سال پیش)
0 0
مرسی. ولی من واقعا هنگ کردم. کلاس Post رو حذف کردم و مستقیم وصل کردم به PostRetrofitModel. و تو PostRetrofitModel هم از حالت آرایه درآوردمو تبدیلش کردم به object. یعنی public User getPosts() و public void setPosts(User posts). توروخدا بیشتر کمک کنید. دارم دیوونه میشم. راستی از طرفی وقتی بجای صدا زدن اسم کلاس در Response از ResponseBody استفاده میکنم کل جیسون رو میتونم دریافت کنم ولی باز تو تبدیل کردن آبجکتهاش مشکل دارم. البته میدونم حالت ResponseBody درست نیست استفاده ش وقتی کلاس بندی صحیحی داشته باشیم. میشه در رابطه با همین جیسون دریافتی من، بفرمایید دقیقا چه کلاس هایی و چه کدهایی داخلش لازمه. خدا خیرتون بده (7 سال پیش)
پاسخ به سوال 
121277  7 سال پیش
+1 0

سلام اقای کریمی

من نمیدونم چه جوری یه قسمت از جسون دریافتی سرور رو مدل سازی کنم

به value توجه کنید هرجا یه فرمتی داره یه جا ارایه است یه جا شیء یه جا هم رشته

چی کار باید بکنم


پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .