Memulai dengan Klien HTTP Retrofit 2
Indonesian (Bahasa Indonesia) translation by Ari Ana (you can also view the original English article)
Apa itu Retrofit?
Retrofit adalah klien HTTP type-safe untuk Android dan Java. Retrofit memudahkan untuk terhubung ke layanan web REST dengan menerjemahkan API ke antarmuka Java. Dalam tutorial ini, saya akan menunjukkan kepada Anda cara menggunakan salah satu perpustakaan HTTP paling populer dan sering direkomendasikan yang tersedia untuk Android.
Perpustakaan yang kuat ini memudahkan untuk mengkonsumsi data JSON atau XML yang kemudian diurai menjadi Plain Old Java Objects (POJOs). Semua permintaan GET, POST, PUT, PATCH, dan DELETE dapat dieksekusi.
Seperti kebanyakan perangkat lunak open-source, Retrofit dibangun di atas beberapa perpustakaan dan alat canggih lainnya. Di belakang layar, Retrofit memanfaatkan OkHttp (dari pengembang yang sama) untuk menangani permintaan jaringan. Selain itu, Retrofit tidak memiliki konverter JSON bawaan untuk mengurai dari JSON ke objek Java. Sebaliknya ia mengirimkan dukungan untuk perpustakaan konverter JSON berikut untuk menanganinya:
- Gson:
com.squareup.retrofit:converter-gson - Jackson:
com.squareup.retrofit:converter-jackson - Moshi:
com.squareup.retrofit:converter-moshi - Protobuf:
com.squareup.retrofit2:converter-protobuf
- Wire:
com.squareup.retrofit2:converter-wire
Dan untuk XML, Retrofit mendukung:
- Simple Framework:
com.squareup.retrofit2:converter-simpleframework
Jadi, Mengapa Menggunakan Retrofit?
Mengembangkan perpustakaan HTTP type-safe Anda sendiri untuk berinteraksi dengan REST API dapat sangat merepotkan: Anda harus menangani banyak fungsi seperti membuat koneksi, menyimpan cache, mencoba kembali permintaan yang gagal, threading, penguraian respons, penanganan kesalahan, dan banyak lagi. Retrofit, di sisi lain, direncanakan dengan sangat baik, didokumentasikan, dan diuji—perpustakaan yang sudah diuji coba yang akan menghemat banyak waktu yang berharga dan sakit kepala.
Dalam tutorial ini, saya akan menjelaskan cara menggunakan Retrofit 2 untuk menangani permintaan jaringan dengan membuat aplikasi sederhana untuk melakukan kueri jawaban terbaru dari API Stack Exchange. Kita akan melakukan permintaan GET dengan menentukan endpoint—/answers, ditambahkan ke URL basis https://api.stackexchange.com/2.2/—lalu mendapatkan hasilnya dan menampilkan dalam view recycler. Saya juga akan menunjukkan kepada Anda bagaimana melakukan ini dengan RxJava untuk pengelolaan aliran data dan status yang mudah.
1. Buatlah Sebuah Proyek Android Studio
Jalankan Android Studio dan buat proyek baru dengan activity kosong yang disebut MainActivity.



2. Mendeklarasikan Dependensi
Setelah membuat proyek baru, deklarasikan dependensi berikut di build.gradle Anda. Dependensi mencakup view recycler, perpustakaan Retrofit, dan juga perpustakaan Gson Google untuk mengonversi JSON menjadi POJO (Plain Old Java Objects) serta integrasi Gson Retrofit.
1 |
// Retrofit
|
2 |
compile 'com.squareup.retrofit2:retrofit:2.1.0' |
3 |
|
4 |
// JSON Parsing
|
5 |
compile 'com.google.code.gson:gson:2.6.1' |
6 |
compile 'com.squareup.retrofit2:converter-gson:2.1.0' |
7 |
|
8 |
// recyclerview
|
9 |
compile 'com.android.support:recyclerview-v7:25.0.1' |
Jangan lupa untuk menyinkronkan proyek untuk mengunduh perpustakaan ini.
3. Menambahkan Perizinan Internet
Untuk melakukan operasi jaringan, kita perlu menyertakan perizinan INTERNET dalam manifest aplikasi: AndroidManifest.xml.
1 |
<?xml version="1.0" encoding="utf-8"?>
|
2 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
3 |
package="com.chikeandroid.retrofittutorial"> |
4 |
|
5 |
<uses-permission android:name="android.permission.INTERNET" /> |
6 |
|
7 |
<application
|
8 |
android:allowBackup="true" |
9 |
android:icon="@mipmap/ic_launcher" |
10 |
android:label="@string/app_name" |
11 |
android:supportsRtl="true" |
12 |
android:theme="@style/AppTheme"> |
13 |
<activity android:name=".MainActivity"> |
14 |
<intent-filter>
|
15 |
<action android:name="android.intent.action.MAIN"/> |
16 |
|
17 |
<category android:name="android.intent.category.LAUNCHER"/> |
18 |
</intent-filter>
|
19 |
</activity>
|
20 |
</application>
|
21 |
|
22 |
</manifest>
|
4. Menghasilkan Model Secara Otomatis
Kita akan membuat model kita secara otomatis dari data respons JSON kita dengan memanfaatkan alat yang sangat berguna: jsonschema2pojo.
Mendapatkan Sampel Data JSON
Salin dan tempel https://api.stackexchange.com/2.2/answers?order=desc&sort=activity&site=stackoverflow di bilah alamat browser Anda (atau Anda bisa menggunakan Postman jika Anda familiar dengan alat tersebut). Kemudian tekan Enter—ini akan mengeksekusi permintaan GET pada endpoint yang diberikan. Apa yang akan Anda lihat sebagai respons adalah array dari objek JSON. Tangkapan layar di bawah ini adalah respons JSON menggunakan Postman.



1 |
{
|
2 |
"items": [ |
3 |
{
|
4 |
"owner": { |
5 |
"reputation": 1, |
6 |
"user_id": 6540831, |
7 |
"user_type": "registered", |
8 |
"profile_image": "https://www.gravatar.com/avatar/6a468ce8a8ff42c17923a6009ab77723?s=128&d=identicon&r=PG&f=1", |
9 |
"display_name": "bobolafrite", |
10 |
"link": "http://stackoverflow.com/users/6540831/bobolafrite" |
11 |
},
|
12 |
"is_accepted": false, |
13 |
"score": 0, |
14 |
"last_activity_date": 1480862271, |
15 |
"creation_date": 1480862271, |
16 |
"answer_id": 40959732, |
17 |
"question_id": 35931342 |
18 |
},
|
19 |
{
|
20 |
"owner": { |
21 |
"reputation": 629, |
22 |
"user_id": 3054722, |
23 |
"user_type": "registered", |
24 |
"profile_image": "https://www.gravatar.com/avatar/0cf65651ae9a3ba2858ef0d0a7dbf900?s=128&d=identicon&r=PG&f=1", |
25 |
"display_name": "jeremy-denis", |
26 |
"link": "http://stackoverflow.com/users/3054722/jeremy-denis" |
27 |
},
|
28 |
"is_accepted": false, |
29 |
"score": 0, |
30 |
"last_activity_date": 1480862260, |
31 |
"creation_date": 1480862260, |
32 |
"answer_id": 40959731, |
33 |
"question_id": 40959661 |
34 |
},
|
35 |
...
|
36 |
],
|
37 |
"has_more": true, |
38 |
"backoff": 10, |
39 |
"quota_max": 300, |
40 |
"quota_remaining": 241 |
41 |
}
|
Respons API untuk permintaan GETSalin respons JSON ini baik dari browser Anda atau Postman.
Memetakan Data JSON ke Java
Sekarang kunjungi jsonschema2pojo dan tempelkan tanggapan JSON ke dalam kotak masukan.
Pilih source type JSON, annotation style Gson, dan hapus centang Allow additional properties.



Kemudian klik tombol Preview untuk menghasilkan objek Java.



Anda mungkin bertanya-tanya apa yang dilakukan oleh anotasi @SerializedName dan @Expose dalam kode yang dihasilkan ini. Jangan khawatir, saya akan menjelaskan semuanya!
Anotasi @SerializedName diperlukan Gson untuk memetakan kunci JSON dengan bidang kita. Sesuai dengan konvensi penamaan camelCase Java untuk properti anggota kelas, tidak disarankan untuk menggunakan garis bawah untuk memisahkan kata-kata dalam sebuah variabel. @SerializedName membantu menerjemahkan di antara keduanya.
1 |
@SerializedName("quota_remaining") |
2 |
@Expose
|
3 |
private Integer quotaRemaining; |
Dalam contoh di atas, kita memberi tahu Gson bahwa kunci quota_remaining JSON kita harus dipetakan ke field Java quotaRemaining. Jika kedua nilai ini sama, yaitu jika kunci JSON kita adalah quotaRemaining sama seperti field Java, maka tidak diperlukan anotasi @SerializedName di field karena Gson akan memetakannya secara otomatis.
Anotasi @Expose menunjukkan bahwa anggota ini harus terbuka untuk serialisasi atau deserialization JSON.
Mengimpor Model Data ke Android Studio
Sekarang mari kembali ke Android Studio. Buat sub-paket baru di dalam paket utama dan beri nama data. Di dalam paket data yang baru dibuat, buat paket lain dan beri nama model. Di dalam paket model, buat kelas Java baru dan beri nama Owner. Sekarang salin kelas Owner yang dihasilkan oleh jsonschema2pojo dan tempelkan di dalam kelas Owner yang Anda buat.
1 |
import com.google.gson.annotations.Expose; |
2 |
import com.google.gson.annotations.SerializedName; |
3 |
|
4 |
public class Owner { |
5 |
|
6 |
@SerializedName("reputation") |
7 |
@Expose
|
8 |
private Integer reputation; |
9 |
@SerializedName("user_id") |
10 |
@Expose
|
11 |
private Integer userId; |
12 |
@SerializedName("user_type") |
13 |
@Expose
|
14 |
private String userType; |
15 |
@SerializedName("profile_image") |
16 |
@Expose
|
17 |
private String profileImage; |
18 |
@SerializedName("display_name") |
19 |
@Expose
|
20 |
private String displayName; |
21 |
@SerializedName("link") |
22 |
@Expose
|
23 |
private String link; |
24 |
@SerializedName("accept_rate") |
25 |
@Expose
|
26 |
private Integer acceptRate; |
27 |
|
28 |
|
29 |
public Integer getReputation() { |
30 |
return reputation; |
31 |
}
|
32 |
|
33 |
public void setReputation(Integer reputation) { |
34 |
this.reputation = reputation; |
35 |
}
|
36 |
|
37 |
public Integer getUserId() { |
38 |
return userId; |
39 |
}
|
40 |
|
41 |
public void setUserId(Integer userId) { |
42 |
this.userId = userId; |
43 |
}
|
44 |
|
45 |
public String getUserType() { |
46 |
return userType; |
47 |
}
|
48 |
|
49 |
public void setUserType(String userType) { |
50 |
this.userType = userType; |
51 |
}
|
52 |
|
53 |
public String getProfileImage() { |
54 |
return profileImage; |
55 |
}
|
56 |
|
57 |
public void setProfileImage(String profileImage) { |
58 |
this.profileImage = profileImage; |
59 |
}
|
60 |
|
61 |
public String getDisplayName() { |
62 |
return displayName; |
63 |
}
|
64 |
|
65 |
public void setDisplayName(String displayName) { |
66 |
this.displayName = displayName; |
67 |
}
|
68 |
|
69 |
public String getLink() { |
70 |
return link; |
71 |
}
|
72 |
|
73 |
public void setLink(String link) { |
74 |
this.link = link; |
75 |
}
|
76 |
|
77 |
public Integer getAcceptRate() { |
78 |
return acceptRate; |
79 |
}
|
80 |
|
81 |
public void setAcceptRate(Integer acceptRate) { |
82 |
this.acceptRate = acceptRate; |
83 |
}
|
84 |
}
|
Lakukan hal yang sama untuk kelas Item baru, disalin dari jsonschema2pojo.
1 |
import com.google.gson.annotations.Expose; |
2 |
import com.google.gson.annotations.SerializedName; |
3 |
|
4 |
public class Item { |
5 |
|
6 |
@SerializedName("owner") |
7 |
@Expose
|
8 |
private Owner owner; |
9 |
@SerializedName("is_accepted") |
10 |
@Expose
|
11 |
private Boolean isAccepted; |
12 |
@SerializedName("score") |
13 |
@Expose
|
14 |
private Integer score; |
15 |
@SerializedName("last_activity_date") |
16 |
@Expose
|
17 |
private Integer lastActivityDate; |
18 |
@SerializedName("creation_date") |
19 |
@Expose
|
20 |
private Integer creationDate; |
21 |
@SerializedName("answer_id") |
22 |
@Expose
|
23 |
private Integer answerId; |
24 |
@SerializedName("question_id") |
25 |
@Expose
|
26 |
private Integer questionId; |
27 |
@SerializedName("last_edit_date") |
28 |
@Expose
|
29 |
private Integer lastEditDate; |
30 |
|
31 |
public Owner getOwner() { |
32 |
return owner; |
33 |
}
|
34 |
|
35 |
public void setOwner(Owner owner) { |
36 |
this.owner = owner; |
37 |
}
|
38 |
|
39 |
public Boolean getIsAccepted() { |
40 |
return isAccepted; |
41 |
}
|
42 |
|
43 |
public void setIsAccepted(Boolean isAccepted) { |
44 |
this.isAccepted = isAccepted; |
45 |
}
|
46 |
|
47 |
public Integer getScore() { |
48 |
return score; |
49 |
}
|
50 |
|
51 |
public void setScore(Integer score) { |
52 |
this.score = score; |
53 |
}
|
54 |
|
55 |
public Integer getLastActivityDate() { |
56 |
return lastActivityDate; |
57 |
}
|
58 |
|
59 |
public void setLastActivityDate(Integer lastActivityDate) { |
60 |
this.lastActivityDate = lastActivityDate; |
61 |
}
|
62 |
|
63 |
public Integer getCreationDate() { |
64 |
return creationDate; |
65 |
}
|
66 |
|
67 |
public void setCreationDate(Integer creationDate) { |
68 |
this.creationDate = creationDate; |
69 |
}
|
70 |
|
71 |
public Integer getAnswerId() { |
72 |
return answerId; |
73 |
}
|
74 |
|
75 |
public void setAnswerId(Integer answerId) { |
76 |
this.answerId = answerId; |
77 |
}
|
78 |
|
79 |
public Integer getQuestionId() { |
80 |
return questionId; |
81 |
}
|
82 |
|
83 |
public void setQuestionId(Integer questionId) { |
84 |
this.questionId = questionId; |
85 |
}
|
86 |
|
87 |
public Integer getLastEditDate() { |
88 |
return lastEditDate; |
89 |
}
|
90 |
|
91 |
public void setLastEditDate(Integer lastEditDate) { |
92 |
this.lastEditDate = lastEditDate; |
93 |
}
|
94 |
}
|
Akhirnya, buat kelas bernama SOAnswersResponse untuk jawaban StackOverflow yang dikembalikan. Anda akan menemukan kode untuk kelas ini di jsonschema2pojo sebagai Example. Pastikan Anda memperbarui nama kelas ke SOAnswersResponse di mana pun itu terjadi.
1 |
import com.google.gson.annotations.Expose; |
2 |
import com.google.gson.annotations.SerializedName; |
3 |
|
4 |
import java.util.List; |
5 |
|
6 |
public class SOAnswersResponse { |
7 |
|
8 |
@SerializedName("items") |
9 |
@Expose
|
10 |
private List<Item> items = null; |
11 |
@SerializedName("has_more") |
12 |
@Expose
|
13 |
private Boolean hasMore; |
14 |
@SerializedName("backoff") |
15 |
@Expose
|
16 |
private Integer backoff; |
17 |
@SerializedName("quota_max") |
18 |
@Expose
|
19 |
private Integer quotaMax; |
20 |
@SerializedName("quota_remaining") |
21 |
@Expose
|
22 |
private Integer quotaRemaining; |
23 |
|
24 |
public List<Item> getItems() { |
25 |
return items; |
26 |
}
|
27 |
|
28 |
public void setItems(List<Item> items) { |
29 |
this.items = items; |
30 |
}
|
31 |
|
32 |
public Boolean getHasMore() { |
33 |
return hasMore; |
34 |
}
|
35 |
|
36 |
public void setHasMore(Boolean hasMore) { |
37 |
this.hasMore = hasMore; |
38 |
}
|
39 |
|
40 |
public Integer getBackoff() { |
41 |
return backoff; |
42 |
}
|
43 |
|
44 |
public void setBackoff(Integer backoff) { |
45 |
this.backoff = backoff; |
46 |
}
|
47 |
|
48 |
public Integer getQuotaMax() { |
49 |
return quotaMax; |
50 |
}
|
51 |
|
52 |
public void setQuotaMax(Integer quotaMax) { |
53 |
this.quotaMax = quotaMax; |
54 |
}
|
55 |
|
56 |
public Integer getQuotaRemaining() { |
57 |
return quotaRemaining; |
58 |
}
|
59 |
|
60 |
public void setQuotaRemaining(Integer quotaRemaining) { |
61 |
this.quotaRemaining = quotaRemaining; |
62 |
}
|
63 |
}
|
5. Membuat Instance Retrofit
Untuk mengeluarkan permintaan jaringan ke REST API dengan Retrofit, kita perlu membuat instance menggunakan kelas Retrofit.Builder dan mengonfigurasinya dengan URL dasar.
Buat paket sub-paket baru di dalam paket data dan beri nama remote. Sekarang di dalam remote, buat kelas Java dan beri nama RetrofitClient. Kelas ini akan membuat singleton dari Retrofit. Retrofit membutuhkan URL dasar untuk membangun instance, sehingga kita akan menyampaikan URL ketika memanggil RetrofitClient.getClient(String baseUrl). URL ini kemudian akan digunakan untuk membangun instance di baris 13. Kita juga menetapkan pengonversi JSON yang kita perlukan (Gson) di baris 14.
1 |
import retrofit2.Retrofit; |
2 |
import retrofit2.converter.gson.GsonConverterFactory; |
3 |
|
4 |
public class RetrofitClient { |
5 |
|
6 |
private static Retrofit retrofit = null; |
7 |
|
8 |
public static Retrofit getClient(String baseUrl) { |
9 |
if (retrofit==null) { |
10 |
retrofit = new Retrofit.Builder() |
11 |
.baseUrl(baseUrl) |
12 |
.addConverterFactory(GsonConverterFactory.create()) |
13 |
.build(); |
14 |
}
|
15 |
return retrofit; |
16 |
}
|
17 |
}
|
6. Membuat Antarmuka API
Di dalam paket remote, buat sebuah antarmuka dan beri nama SOService. Antarmuka ini berisi metode yang akan kita gunakan untuk mengeksekusi permintaan HTTP seperti GET, POST, PUT, PATCH, dan DELETE. Untuk tutorial ini, kita akan menjalankan permintaan GET.
1 |
import com.chikeandroid.retrofittutorial.data.model.SOAnswersResponse; |
2 |
|
3 |
import java.util.List; |
4 |
|
5 |
import retrofit2.Call; |
6 |
import retrofit2.http.GET; |
7 |
|
8 |
public interface SOService { |
9 |
|
10 |
@GET("/answers?order=desc&sort=activity&site=stackoverflow") |
11 |
Call<List<SOAnswersResponse>> getAnswers(); |
12 |
|
13 |
@GET("/answers?order=desc&sort=activity&site=stackoverflow") |
14 |
Call<List<SOAnswersResponse>> getAnswers(@Query("tagged") String tags); |
15 |
}
|
Anotasi @GET secara eksplisit mendefinisikan permintaan GET yang akan dijalankan setelah metode dipanggil. Setiap metode dalam antarmuka ini harus memiliki anotasi HTTP yang menyediakan metode permintaan dan URL relatif. Ada lima anotasi bawaan yang tersedia: @GET, @POST, @PUT, @DELETE, dan @HEAD.
Dalam definisi metode kedua, kita menambahkan parameter kueri agar kita dapat menyaring data dari server. Retrofit memiliki anotasi @Query("key") untuk digunakan sebagai pengganti pengkodean manual di endpoint. Nilai key mewakili nama parameter di URL. Ini akan ditambahkan ke URL oleh Retrofit. Misalnya, jika kita mengirimkan nilai "android" sebagai argumen ke metode getAnswers(String tags), URL lengkapnya adalah:
1 |
https://api.stackexchange.com/2.2/answers?order=desc&sort=activity&site=stackoverflow&tagged=android |
Parameter metode antarmuka dapat memiliki anotasi berikut:
@Path | substitusi variabel untuk endpoint API |
@Query | menentukan nama kunci kueri dengan nilai parameter beranotasi |
@Body | payload untuk panggilan POST |
@Header | menentukan header dengan nilai parameter beranotasi |
7. Menciptakan Utilitas API
Sekarang akan membuat kelas utilitas. Kita akan menamakannya ApiUtils. Kelas ini akan memiliki URL dasar sebagai variabel static dan juga menyediakan antarmuka SOService ke aplikasi kita melalui metode static getSOService().
1 |
public class ApiUtils { |
2 |
|
3 |
public static final String BASE_URL = "https://api.stackexchange.com/2.2"; |
4 |
|
5 |
public static SOService getSOService() { |
6 |
return RetrofitClient.getClient(BASE_URL).create(SOService.class); |
7 |
}
|
8 |
}
|
8. Menampilkan ke RecyclerView
Karena hasilnya akan ditampilkan dalam view recycler, kita membutuhkan sebuah adaptor. Potongan kode berikut menunjukkan kelas AnswersAdapter.
1 |
public class AnswersAdapter extends RecyclerView.Adapter<AnswersAdapter.ViewHolder> { |
2 |
|
3 |
private List<Item> mItems; |
4 |
private Context mContext; |
5 |
private PostItemListener mItemListener; |
6 |
|
7 |
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ |
8 |
|
9 |
public TextView titleTv; |
10 |
PostItemListener mItemListener; |
11 |
|
12 |
public ViewHolder(View itemView, PostItemListener postItemListener) { |
13 |
super(itemView); |
14 |
titleTv = (TextView) itemView.findViewById(android.R.id.text1); |
15 |
|
16 |
this.mItemListener = postItemListener; |
17 |
itemView.setOnClickListener(this); |
18 |
}
|
19 |
|
20 |
@Override
|
21 |
public void onClick(View view) { |
22 |
Item item = getItem(getAdapterPosition()); |
23 |
this.mItemListener.onPostClick(item.getAnswerId()); |
24 |
|
25 |
notifyDataSetChanged(); |
26 |
}
|
27 |
}
|
28 |
|
29 |
public AnswersAdapter(Context context, List<Item> posts, PostItemListener itemListener) { |
30 |
mItems = posts; |
31 |
mContext = context; |
32 |
mItemListener = itemListener; |
33 |
}
|
34 |
|
35 |
@Override
|
36 |
public AnswersAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { |
37 |
|
38 |
Context context = parent.getContext(); |
39 |
LayoutInflater inflater = LayoutInflater.from(context); |
40 |
|
41 |
View postView = inflater.inflate(android.R.layout.simple_list_item_1, parent, false); |
42 |
|
43 |
ViewHolder viewHolder = new ViewHolder(postView, this.mItemListener); |
44 |
return viewHolder; |
45 |
}
|
46 |
|
47 |
@Override
|
48 |
public void onBindViewHolder(AnswersAdapter.ViewHolder holder, int position) { |
49 |
|
50 |
Item item = mItems.get(position); |
51 |
TextView textView = holder.titleTv; |
52 |
textView.setText(item.getOwner().getDisplayName()); |
53 |
}
|
54 |
|
55 |
@Override
|
56 |
public int getItemCount() { |
57 |
return mItems.size(); |
58 |
}
|
59 |
|
60 |
public void updateAnswers(List<Item> items) { |
61 |
mItems = items; |
62 |
notifyDataSetChanged(); |
63 |
}
|
64 |
|
65 |
private Item getItem(int adapterPosition) { |
66 |
return mItems.get(adapterPosition); |
67 |
}
|
68 |
|
69 |
public interface PostItemListener { |
70 |
void onPostClick(long id); |
71 |
}
|
72 |
}
|
9. Melaksanakan Permintaan
Di dalam metode onCreate() dari MainActivity, kita menginisialisasi instance antarmuka SOService (baris 9), view recycler, dan juga adaptor. Akhirnya, kita memanggil metode loadAnswers().
1 |
private AnswersAdapter mAdapter; |
2 |
private RecyclerView mRecyclerView; |
3 |
private SOService mService; |
4 |
|
5 |
@Override
|
6 |
protected void onCreate (Bundle savedInstanceState) { |
7 |
super.onCreate( savedInstanceState ); |
8 |
setContentView(R.layout.activity_main ); |
9 |
mService = ApiUtils.getSOService(); |
10 |
mRecyclerView = (RecyclerView) findViewById(R.id.rv_answers); |
11 |
mAdapter = new AnswersAdapter(this, new ArrayList<Item>(0), new AnswersAdapter.PostItemListener() { |
12 |
|
13 |
@Override
|
14 |
public void onPostClick(long id) { |
15 |
Toast.makeText(MainActivity.this, "Post id is" + id, Toast.LENGTH_SHORT).show(); |
16 |
}
|
17 |
});
|
18 |
|
19 |
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this); |
20 |
mRecyclerView.setLayoutManager(layoutManager); |
21 |
mRecyclerView.setAdapter(mAdapter); |
22 |
mRecyclerView.setHasFixedSize(true); |
23 |
RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST); |
24 |
mRecyclerView.addItemDecoration(itemDecoration); |
25 |
|
26 |
loadAnswers(); |
27 |
}
|
Metode loadAnswers() membuat permintaan jaringan dengan memanggil enqueue(). Ketika respons kembali, Retrofit membantu kita untuk menguraikan respons JSON ke daftar objek Java. (Ini dimungkinkan dengan menggunakan GsonConverter.)
1 |
public void loadAnswers() { |
2 |
mService.getAnswers().enqueue(new Callback<SOAnswersResponse>() { |
3 |
@Override
|
4 |
public void onResponse(Call<SOAnswersResponse> call, Response<SOAnswersResponse> response) { |
5 |
|
6 |
if(response.isSuccessful()) { |
7 |
mAdapter.updateAnswers(response.body().getItems()); |
8 |
Log.d("MainActivity", "posts loaded from API"); |
9 |
}else { |
10 |
int statusCode = response.code(); |
11 |
// handle request errors depending on status code
|
12 |
}
|
13 |
}
|
14 |
|
15 |
@Override
|
16 |
public void onFailure(Call<SOAnswersResponse> call, Throwable t) { |
17 |
showErrorMessage(); |
18 |
Log.d("MainActivity", "error loading from API"); |
19 |
|
20 |
}
|
21 |
});
|
22 |
}
|
10. Memahami enqueue()
enqueue() secara asinkron mengirim permintaan dan memberi tahu aplikasi Anda dengan callback ketika respons datang kembali. Karena permintaan ini asinkron, Retrofit menanganinya di thread latar sehingga thread UI utama tidak diblokir atau terganggu.
Untuk menggunakan enqueue(), Anda harus menerapkan dua metode callback:
onResponse()onFailure()
Hanya satu dari metode ini yang akan dipanggil untuk menanggapi permintaan yang diberikan.
-
onResponse(): dipanggil untuk respons HTTP yang diterima. Metode ini dipanggil untuk respons yang dapat ditangani dengan benar bahkan jika server mengembalikan pesan kesalahan. Jadi, jika Anda mendapatkan kode status 404 atau 500, metode ini masih akan dipanggil. Untuk mendapatkan kode status agar Anda dapat menangani situasi berdasarkan pada mereka, Anda dapat menggunakan metoderesponse.code(). Anda juga dapat menggunakan metodeisSuccessful()untuk mencari tahu apakah kode status ada dalam rentang 200-300, yang menunjukkan keberhasilan. -
onFailure(): dipanggil ketika exception jaringan terjadi berkomunikasi ke server atau ketika exception yang tidak terduga terjadi menangani permintaan atau memproses respons.
Untuk melakukan permintaan sinkron, Anda bisa menggunakan metode execute(). Ketahuilah bahwa metode sinkron pada thread main/UI akan memblokir setiap tindakan pengguna. Jadi, jangan jalankan metode sinkron pada thread main/UI Android! Sebagai gantinya, jalankan pada thread latar belakang.
11. Menguji Aplikasi
Anda sekarang dapat menjalankan aplikasinya.
12. Integrasi RxJava
Jika Anda penggemar RxJava, Anda dapat dengan mudah menerapkan Retrofit dengan RxJava. Di Retrofit 1 itu terintegrasi secara default, tetapi di Retrofit 2 Anda perlu menyertakan beberapa dependensi tambahan. Retrofit dikirim dengan adaptor default untuk menjalankan instance Call. Jadi Anda dapat mengubah mekanisme eksekusi Retrofit untuk memasukkan RxJava dengan menyertakan RxJava CallAdapter.
Langkah 1
Menambahkan dependensi.
1 |
compile 'io.reactivex:rxjava:1.1.6' |
2 |
compile 'io.reactivex:rxandroid:1.2.1' |
3 |
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0' |
Langkah 2
Tambahkan CallAdapter baru RxJavaCallAdapterFactory.create() saat membangun instance Retrofit.
1 |
public static Retrofit getClient(String baseUrl) { |
2 |
if (retrofit==null) { |
3 |
retrofit = new Retrofit.Builder() |
4 |
.baseUrl(baseUrl) |
5 |
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) |
6 |
.addConverterFactory(GsonConverterFactory.create()) |
7 |
.build(); |
8 |
}
|
9 |
return retrofit; |
10 |
}
|
Langkah 3
Ketika membuat permintaan, pelanggan anonim kita menanggapi aliran yang dapat diamati yang memancarkan kejadian, dalam kasus kita SOAnswersResponse. Metode onNext kemudian dipanggil ketika pelanggan kita menerima peristiwa apa pun yang dipancarkan yang kemudian diteruskan ke adaptor kita.
1 |
@Override |
2 |
public void loadAnswers() {
|
3 |
mService.getAnswers().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) |
4 |
.subscribe(new Subscriber<SOAnswersResponse>() {
|
5 |
@Override |
6 |
public void onCompleted() {
|
7 |
|
8 |
} |
9 |
|
10 |
@Override |
11 |
public void onError(Throwable e) {
|
12 |
|
13 |
} |
14 |
|
15 |
@Override |
16 |
public void onNext(SOAnswersResponse soAnswersResponse) {
|
17 |
mAdapter.updateAnswers(soAnswersResponse.getItems()); |
18 |
} |
19 |
}); |
20 |
} |
Lihat Memulai dengan ReactiveX di Android oleh Ashraff Hathibelagal untuk mempelajari lebih lanjut tentang RxJava dan RxAndroid.
Kesimpulan
Dalam tutorial ini, Anda belajar tentang Retrofit: mengapa Anda harus menggunakannya dan caranya. Saya juga menjelaskan cara menambahkan integrasi RxJava dengan Retrofit. Dalam posting saya berikutnya, saya akan menunjukkan kepada Anda cara melakukan POST, PUT, dan DELETE, cara mengirim data Form-Urlencoded, dan cara membatalkan permintaan.
Untuk mempelajari lebih lanjut tentang Retrofit, silakan lihat dokumentasi resminya. Dan sementara itu, periksa beberapa kursus dan tutorial kami lainnya tentang pengembangan aplikasi Android.


.png)
.png)







