Что такое модернизация?
Retrofit — это безопасный для типов HTTP-клиент для Android и Java. Модернизация позволяет легко подключаться к веб-службе REST путем перевода API в интерфейсы Java. В этом руководстве я покажу вам, как использовать одну из самых популярных и часто рекомендуемых библиотек HTTP, доступных для Android.
Эта мощная библиотека позволяет легко использовать данные JSON или XML, которые затем анализируются в простые старые объекты Java (POJO). Запросы GET
, POST
, PUT
, PATCH
и DELETE
могут быть выполнены.
Как и большинство программного обеспечения с открытым исходным кодом, Retrofit был построен поверх некоторых других мощных библиотек и инструментов. За кулисами Retrofit использует OkHttp (от того же разработчика) для обработки сетевых запросов. Кроме того, Retrofit не имеет встроенного конвертера JSON для анализа объектов JSON в Java. Вместо этого он поддерживает следующие библиотеки JSON-конвертеров:
- Gson:
com.squareup.retrofit:converter-gson
- Джексон:
com.squareup.retrofit:converter-jackson
- Моши:
com.squareup.retrofit:converter-moshi
Для буферов протокола Retrofit поддерживает:
- Protobuf:
com.squareup.retrofit2:converter-protobuf
- Провод:
com.squareup.retrofit2:converter-wire
А для XML Retrofit поддерживает:
- Простая структура:
com.squareup.retrofit2:converter-simpleframework
Так зачем использовать модернизацию?
Разработка собственной безопасной HTTP-библиотеки для взаимодействия с REST API может быть очень сложной задачей: вам приходится работать со многими функциями, такими как создание соединений, кэширование, повторение неудачных запросов, многопоточность, анализ ответов, обработка ошибок и многое другое. С другой стороны, дооснащение очень хорошо спланировано, задокументировано и протестировано — проверенная в сражениях библиотека, которая сэкономит вам много драгоценного времени и головной боли.
В этом руководстве я объясню, как использовать Retrofit 2 для обработки сетевых запросов, создав простое приложение для запроса последних ответов из Stack Exchange API. Мы GET
запросы GET
, указав конечную точку — /answers
answers, добавленную к базовому URL-адресу https://api.stackexchange.com/2.2 /, — затем получим результаты и отобразим их в виде переработчика. Я также покажу вам, как это сделать с помощью RxJava для удобного управления потоком состояний и данных.
1. Создайте проект Android Studio
MainActivity
Android Studio и создайте новый проект с пустым действием MainActivity
.
2. Объявление зависимостей
После создания нового проекта объявите следующие зависимости в вашем build.gradle
. Зависимости включают в себя представление переработчика, библиотеку Retrofit, а также библиотеку Google Gson для преобразования JSON в POJO (простые старые объекты Java), а также интеграцию Retrofit Gson.
1
2
3
4
5
6
7
8
9
|
// Retrofit
compile ‘com.squareup.retrofit2:retrofit:2.1.0’
// JSON Parsing
compile ‘com.google.code.gson:gson:2.6.1’
compile ‘com.squareup.retrofit2:converter-gson:2.1.0’
// recyclerview
compile ‘com.android.support:recyclerview-v7:25.0.1’
|
Не забудьте синхронизировать проект для загрузки этих библиотек.
3. Добавление интернет-разрешения
Для выполнения сетевых операций нам нужно включить INTERNET
разрешение в манифесте приложения: AndroidManifest.xml .
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?xml version=»1.0″ encoding=»utf-8″?>
<manifest xmlns:android=»http://schemas.android.com/apk/res/android»
package=»com.chikeandroid.retrofittutorial»>
<uses-permission android:name=»android.permission.INTERNET» />
<application
android:allowBackup=»true»
android:icon=»@mipmap/ic_launcher»
android:label=»@string/app_name»
android:supportsRtl=»true»
android:theme=»@style/AppTheme»>
<activity android:name=».MainActivity»>
<intent-filter>
<action android:name=»android.intent.action.MAIN»/>
<category android:name=»android.intent.category.LAUNCHER»/>
</intent-filter>
</activity>
</application>
</manifest>
|
4. Генерация моделей автоматически
Мы собираемся создавать наши модели автоматически из наших данных ответов JSON, используя очень полезный инструмент: jsonschema2pojo .
Получить образец данных JSON
Скопируйте и вставьте https://api.stackexchange.com/2.2/answers?order=desc&sort=activity&site=stackoverflow в адресную строку браузера (или вы можете использовать Postman, если вы знакомы с этим инструментом). Затем нажмите Enter — это выполнит запрос GET для данной конечной точки. В ответ вы увидите массив JSON-объектов. На снимке экрана ниже показан ответ JSON с использованием Postman.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
{
«items»: [
{
«owner»: {
«reputation»: 1,
«user_id»: 6540831,
«user_type»: «registered»,
«profile_image»: «https://www.gravatar.com/avatar/6a468ce8a8ff42c17923a6009ab77723?s=128&d=identicon&r=PG&f=1»,
«display_name»: «bobolafrite»,
«link»: «http://stackoverflow.com/users/6540831/bobolafrite»
},
«is_accepted»: false,
«score»: 0,
«last_activity_date»: 1480862271,
«creation_date»: 1480862271,
«answer_id»: 40959732,
«question_id»: 35931342
},
{
«owner»: {
«reputation»: 629,
«user_id»: 3054722,
«user_type»: «registered»,
«profile_image»: «https://www.gravatar.com/avatar/0cf65651ae9a3ba2858ef0d0a7dbf900?s=128&d=identicon&r=PG&f=1»,
«display_name»: «jeremy-denis»,
«link»: «http://stackoverflow.com/users/3054722/jeremy-denis»
},
«is_accepted»: false,
«score»: 0,
«last_activity_date»: 1480862260,
«creation_date»: 1480862260,
«answer_id»: 40959731,
«question_id»: 40959661
},
…
],
«has_more»: true,
«backoff»: 10,
«quota_max»: 300,
«quota_remaining»: 241
}
|
Скопируйте этот ответ JSON либо из браузера, либо из Почтальона.
Сопоставьте данные JSON с Java
Теперь посетите jsonschema2pojo и вставьте ответ JSON в поле ввода.
Выберите тип источника JSON , стиль аннотации Gson и снимите флажок Разрешить дополнительные свойства .
Затем нажмите кнопку « Просмотр» , чтобы сгенерировать объекты Java.
Вам может быть интересно, что @SerializedName
аннотации @SerializedName
и @Expose
в этом сгенерированном коде. Не волнуйся, я все объясню!
Аннотация @SerializedName
необходима Gson для сопоставления ключей JSON с нашими полями. В соответствии с соглашением Java о присвоении имен camelCase для свойств членов класса, не рекомендуется использовать подчеркивания для разделения слов в переменной. @SerializedName
помогает переводить между двумя.
1
2
3
|
@SerializedName(«quota_remaining»)
@Expose
private Integer quotaRemaining;
|
В приведенном выше примере мы говорим Gson, что наш ключ JSON quota_remaining
должен быть сопоставлен с полем Java quotaRemaining
. Если бы оба эти значения были одинаковыми, т. quotaRemaining
Если бы наш JSON-ключ был quotaRemaining
как и поле Java, тогда не было бы необходимости в аннотации @SerializedName
для поля, потому что Gson отобразил бы их автоматически.
Аннотация @Expose
указывает, что этот член должен быть @Expose
для сериализации или десериализации JSON.
Импорт моделей данных в Android Studio
Теперь вернемся к Android Studio. Создайте новый подпакет внутри основного пакета и назовите его data . Внутри нового пакета данных создайте другой пакет и назовите его модель . Внутри модельного пакета создайте новый класс Java и назовите его Owner
. Теперь скопируйте класс Owner
, созданный jsonschema2pojo, и вставьте его в созданный вами класс Owner
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Owner {
@SerializedName(«reputation»)
@Expose
private Integer reputation;
@SerializedName(«user_id»)
@Expose
private Integer userId;
@SerializedName(«user_type»)
@Expose
private String userType;
@SerializedName(«profile_image»)
@Expose
private String profileImage;
@SerializedName(«display_name»)
@Expose
private String displayName;
@SerializedName(«link»)
@Expose
private String link;
@SerializedName(«accept_rate»)
@Expose
private Integer acceptRate;
public Integer getReputation() {
return reputation;
}
public void setReputation(Integer reputation) {
this.reputation = reputation;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
public String getProfileImage() {
return profileImage;
}
public void setProfileImage(String profileImage) {
this.profileImage = profileImage;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public Integer getAcceptRate() {
return acceptRate;
}
public void setAcceptRate(Integer acceptRate) {
this.acceptRate = acceptRate;
}
}
|
Сделайте то же самое для нового класса Item
, скопированного из jsonschema2pojo.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Item {
@SerializedName(«owner»)
@Expose
private Owner owner;
@SerializedName(«is_accepted»)
@Expose
private Boolean isAccepted;
@SerializedName(«score»)
@Expose
private Integer score;
@SerializedName(«last_activity_date»)
@Expose
private Integer lastActivityDate;
@SerializedName(«creation_date»)
@Expose
private Integer creationDate;
@SerializedName(«answer_id»)
@Expose
private Integer answerId;
@SerializedName(«question_id»)
@Expose
private Integer questionId;
@SerializedName(«last_edit_date»)
@Expose
private Integer lastEditDate;
public Owner getOwner() {
return owner;
}
public void setOwner(Owner owner) {
this.owner = owner;
}
public Boolean getIsAccepted() {
return isAccepted;
}
public void setIsAccepted(Boolean isAccepted) {
this.isAccepted = isAccepted;
}
public Integer getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
public Integer getLastActivityDate() {
return lastActivityDate;
}
public void setLastActivityDate(Integer lastActivityDate) {
this.lastActivityDate = lastActivityDate;
}
public Integer getCreationDate() {
return creationDate;
}
public void setCreationDate(Integer creationDate) {
this.creationDate = creationDate;
}
public Integer getAnswerId() {
return answerId;
}
public void setAnswerId(Integer answerId) {
this.answerId = answerId;
}
public Integer getQuestionId() {
return questionId;
}
public void setQuestionId(Integer questionId) {
this.questionId = questionId;
}
public Integer getLastEditDate() {
return lastEditDate;
}
public void setLastEditDate(Integer lastEditDate) {
this.lastEditDate = lastEditDate;
}
}
|
Наконец, создайте класс с именем SOAnswersResponse
для возвращенных ответов StackOverflow. Вы найдете код для этого класса в jsonschema2pojo в качестве Example
. Убедитесь, что вы обновили имя класса до SOAnswersResponse
где бы оно ни происходило.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class SOAnswersResponse {
@SerializedName(«items»)
@Expose
private List<Item> items = null;
@SerializedName(«has_more»)
@Expose
private Boolean hasMore;
@SerializedName(«backoff»)
@Expose
private Integer backoff;
@SerializedName(«quota_max»)
@Expose
private Integer quotaMax;
@SerializedName(«quota_remaining»)
@Expose
private Integer quotaRemaining;
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
public Boolean getHasMore() {
return hasMore;
}
public void setHasMore(Boolean hasMore) {
this.hasMore = hasMore;
}
public Integer getBackoff() {
return backoff;
}
public void setBackoff(Integer backoff) {
this.backoff = backoff;
}
public Integer getQuotaMax() {
return quotaMax;
}
public void setQuotaMax(Integer quotaMax) {
this.quotaMax = quotaMax;
}
public Integer getQuotaRemaining() {
return quotaRemaining;
}
public void setQuotaRemaining(Integer quotaRemaining) {
this.quotaRemaining = quotaRemaining;
}
}
|
5. Создание экземпляра модернизации
Чтобы отправлять сетевые запросы к REST API с Retrofit, нам нужно создать экземпляр с помощью класса Retrofit.Builder
и настроить его с помощью базового URL.
Создайте новый пакет подпакета внутри пакета data
и назовите его remote
. Теперь внутри remote
создайте класс Java и назовите его RetrofitClient
. Этот класс создаст синглтон Retrofit. Для модификации необходим базовый URL-адрес для создания своего экземпляра, поэтому мы будем передавать URL-адрес при вызове RetrofitClient.getClient(String baseUrl)
. Затем этот URL будет использоваться для построения экземпляра в строке 13. Мы также указываем нужный нам JSON-конвертер (Gson) в строке 14.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String baseUrl) {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
|
6. Создание интерфейса API
Внутри удаленного пакета создайте интерфейс и назовите его SOService
. Этот интерфейс содержит методы, которые мы собираемся использовать для выполнения HTTP-запросов, таких как GET
, POST
, PUT
, PATCH
и DELETE
. Для этого урока мы собираемся выполнить запрос GET
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
import com.chikeandroid.retrofittutorial.data.model.SOAnswersResponse;
import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;
public interface SOService {
@GET(«/answers?order=desc&sort=activity&site=stackoverflow»)
Call<SOAnswersResponse> getAnswers();
@GET(«/answers?order=desc&sort=activity&site=stackoverflow»)
Call<SOAnswersResponse> getAnswers(@Query(«tagged») String tags);
}
|
Аннотация @GET
явно определяет тот GET
который будет выполнен после @GET
метода. Каждый метод в этом интерфейсе должен иметь аннотацию HTTP, которая предоставляет метод запроса и относительный URL. Доступно пять встроенных аннотаций: @GET
, @POST
, @PUT
, @DELETE
и @HEAD
.
Во втором определении метода мы добавили параметр запроса для фильтрации данных с сервера. Retrofit имеет @Query("key")
можно использовать вместо жесткого кодирования в конечной точке. Значение ключа представляет имя параметра в URL. Он будет добавлен в URL при помощи Retrofit. Например, если мы передадим значение "android"
в качестве аргумента getAnswers(String tags)
, полный URL будет:
1
|
https://api.stackexchange.com/2.2/answers?order=desc&sort=activity&site=stackoverflow&tagged=android
|
Параметры методов интерфейса могут иметь следующие аннотации:
@Path |
подстановка переменных для конечной точки API |
@Query |
указывает имя ключа запроса со значением аннотированного параметра |
@Body |
полезная нагрузка для вызова POST |
@Header |
указывает заголовок со значением аннотированного параметра |
7. Создание утилит API
Теперь собираемся создать служебный класс. Мы ApiUtils
это ApiUtils
. Этот класс будет иметь базовый URL-адрес в качестве статической переменной, а также предоставлять интерфейс SOService
нашему приложению через статический метод getSOService()
.
1
2
3
4
5
6
7
8
|
public class ApiUtils {
public static final String BASE_URL = «https://api.stackexchange.com/2.2/»;
public static SOService getSOService() {
return RetrofitClient.getClient(BASE_URL).create(SOService.class);
}
}
|
8. Отображение в RecyclerView
Так как результаты будут отображаться в виде переработчика , нам нужен адаптер. В следующем фрагменте кода показан класс AnswersAdapter
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
public class AnswersAdapter extends RecyclerView.Adapter<AnswersAdapter.ViewHolder> {
private List<Item> mItems;
private Context mContext;
private PostItemListener mItemListener;
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView titleTv;
PostItemListener mItemListener;
public ViewHolder(View itemView, PostItemListener postItemListener) {
super(itemView);
titleTv = (TextView) itemView.findViewById(android.R.id.text1);
this.mItemListener = postItemListener;
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
Item item = getItem(getAdapterPosition());
this.mItemListener.onPostClick(item.getAnswerId());
notifyDataSetChanged();
}
}
public AnswersAdapter(Context context, List<Item> posts, PostItemListener itemListener) {
mItems = posts;
mContext = context;
mItemListener = itemListener;
}
@Override
public AnswersAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View postView = inflater.inflate(android.R.layout.simple_list_item_1, parent, false);
ViewHolder viewHolder = new ViewHolder(postView, this.mItemListener);
return viewHolder;
}
@Override
public void onBindViewHolder(AnswersAdapter.ViewHolder holder, int position) {
Item item = mItems.get(position);
TextView textView = holder.titleTv;
textView.setText(item.getOwner().getDisplayName());
}
@Override
public int getItemCount() {
return mItems.size();
}
public void updateAnswers(List<Item> items) {
mItems = items;
notifyDataSetChanged();
}
private Item getItem(int adapterPosition) {
return mItems.get(adapterPosition);
}
public interface PostItemListener {
void onPostClick(long id);
}
}
|
9. Выполнение запроса
Внутри onCreate()
объекта MainActivity
мы инициализируем экземпляр интерфейса SOService
(строка 9), представление рециркулятора, а также адаптер. Наконец, мы вызываем метод loadAnswers()
.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
private AnswersAdapter mAdapter;
private RecyclerView mRecyclerView;
private SOService mService;
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView(R.layout.activity_main );
mService = ApiUtils.getSOService();
mRecyclerView = (RecyclerView) findViewById(R.id.rv_answers);
mAdapter = new AnswersAdapter(this, new ArrayList<Item>(0), new AnswersAdapter.PostItemListener() {
@Override
public void onPostClick(long id) {
Toast.makeText(MainActivity.this, «Post id is» + id, Toast.LENGTH_SHORT).show();
}
});
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setHasFixedSize(true);
RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST);
mRecyclerView.addItemDecoration(itemDecoration);
loadAnswers();
}
|
Метод loadAnswers()
создает сетевой запрос, вызывая enqueue()
. Когда ответ возвращается, Retrofit помогает нам проанализировать ответ JSON для списка объектов Java. (Это стало возможным благодаря использованию GsonConverter
.)
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public void loadAnswers() {
mService.getAnswers().enqueue(new Callback<SOAnswersResponse>() {
@Override
public void onResponse(Call<SOAnswersResponse> call, Response<SOAnswersResponse> response) {
if(response.isSuccessful()) {
mAdapter.updateAnswers(response.body().getItems());
Log.d(«MainActivity», «posts loaded from API»);
}else {
int statusCode = response.code();
// handle request errors depending on status code
}
}
@Override
public void onFailure(Call<SOAnswersResponse> call, Throwable t) {
showErrorMessage();
Log.d(«MainActivity», «error loading from API»);
}
});
}
|
10. Понимание enqueue()
enqueue()
асинхронно отправляет запрос и уведомляет ваше приложение обратным вызовом, когда возвращается ответ. Поскольку этот запрос является асинхронным, Retrofit обрабатывает его в фоновом потоке, чтобы основной поток пользовательского интерфейса не блокировался и не мешал.
Чтобы использовать enqueue()
, вы должны реализовать два метода обратного вызова:
-
onResponse()
-
onFailure()
Только один из этих методов будет вызван в ответ на данный запрос.
-
onResponse()
: вызывается для полученного ответа HTTP. Этот метод вызывается для ответа, который можно правильно обработать, даже если сервер возвращает сообщение об ошибке. Поэтому, если вы получите код состояния 404 или 500, этот метод все равно будет вызываться. Чтобы получить код состояния для обработки ситуаций на их основе, вы можете использовать методresponse.code()
. Вы также можете использовать методisSuccessful()
чтобы выяснить, находится ли код состояния в диапазоне 200-300, что указывает на успех. -
onFailure()
: вызывается, когда при подключении к серверу возникло сетевое исключение или произошло непредвиденное исключение при обработке запроса или обработке ответа.
Для выполнения синхронного запроса вы можете использовать метод execute()
. Имейте в виду, что синхронные методы в основном потоке / интерфейсе пользователя блокируют любые действия пользователя Поэтому не выполняйте синхронные методы в основном потоке Android / пользовательском интерфейсе! Вместо этого запустите их в фоновом потоке.
11. Тестирование приложения
Теперь вы можете запустить приложение.
12. Интеграция с RxJava
Если вы являетесь поклонником RxJava, вы можете легко реализовать Retrofit с помощью RxJava. В Retrofit 1 он был интегрирован по умолчанию, но в Retrofit 2 вам необходимо включить некоторые дополнительные зависимости. Модификация поставляется с адаптером по умолчанию для выполнения экземпляров Call
. Таким образом, вы можете изменить механизм выполнения Retrofit, включив в него RxJava, включив RxJava CallAdapter
.
Шаг 1
Добавьте зависимости.
1
2
3
|
compile ‘io.reactivex:rxjava:1.1.6’
compile ‘io.reactivex:rxandroid:1.2.1’
compile ‘com.squareup.retrofit2:adapter-rxjava:2.1.0’
|
Шаг 2
Добавьте новый CallAdapter RxJavaCallAdapterFactory.create()
при создании экземпляра Retrofit.
01
02
03
04
05
06
07
08
09
10
|
public static Retrofit getClient(String baseUrl) {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
|
Шаг 3
Теперь обновите методы getAnswers()
чтобы они возвращали Observable
s:
1
2
3
4
5
|
@GET(«/answers?order=desc&sort=activity&site=stackoverflow»)
Observable<SOAnswersResponse> getAnswers();
@GET(«/answers?order=desc&sort=activity&site=stackoverflow»)
Observable<SOAnswersResponse> getAnswers(@Query(«tagged») String tags);
|
Шаг 4
При выполнении запросов наш анонимный подписчик отвечает на поток наблюдаемой, который генерирует события, в нашем случае SOAnswersResponse
. Затем метод onNext
вызывается, когда наш подписчик получает любое событие, которое onNext
а затем передается нашему адаптеру.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
@Override
public void loadAnswers() {
mService.getAnswers().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<SOAnswersResponse>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(SOAnswersResponse soAnswersResponse) {
mAdapter.updateAnswers(soAnswersResponse.getItems());
}
});
}
|
Чтобы узнать больше о RxJava и RxAndroid, ознакомьтесь с разделом Начало работы с ReactiveX на Android от Ашрафа Хатибелагала.
Вывод
В этом уроке вы узнали о Retrofit: почему вы должны его использовать и как. Я также объяснил, как добавить интеграцию RxJava с Retrofit. В моем следующем посте я покажу вам, как выполнять POST
, PUT
и DELETE
, как отправлять данные в Form-Urlencoded
и как отменять запросы.
Чтобы узнать больше о модернизации, обратитесь к официальной документации . А пока ознакомьтесь с другими нашими курсами и учебными пособиями по разработке приложений для Android.