Coders Lab 128 #1 Napisano 17 Grudnia 2018 Retrofit 2.x jest klientem REST dla Javy. W związku z tym, można również używać go do komunikacji z serwerem w Androidzie . Na początek należy dodać odpowiednie zależności do projektu: dependencies { ... // retrofit implementation 'com.squareup.retrofit2:retrofit:2.3.0' implementation 'com.squareup.retrofit2:converter-gson:2.3.0' ... } Następnie trzeba stworzyć: klasę modelu, która będzie wysyłana na serwer lub zwracana z serwera jako JSON interfejs, w którym będą zdefiniowane operacje HTTP obiekt typu Retrofit z podanym url do którego będą wykonywane requesty i wskazać mu interfejs z metodami HTTP Model W tym przykładzie posłużę się json-serverem z domyślną konfiguracją podaną w Getting Started jako serwisem do którego będę tworzył zapytania. Mój plik db.json wygląda następująco: { "posts": [ { "id": 1, "title": "json-server", "author": "typicode" } ], "comments": [ { "id": 1, "body": "some comment", "postId": 1 } ], "profile": { "name": "typicode" } } Na jego podstawię za pomocą wtyczki JSON To Kotlin Class tworzę klasy w moim projekcie: Klasa Post: data class Post( val author: String, val id: Int, val title: String ) Klasa Comment: data class Comment( val body: String, val id: Int, val postId: Int ) Klasa Profile: data class Profile( val name: String ) Interfejs W interfejsie definiuje metody HTTP które będą służyć do pobierania informacji z serwera: interface RestAPI { //pobranie wszystkich postów podanego autora @GET("/posts") fun getPostsByAuthor(@Query("author") author: String): Call<List<Post>> //pobranie wszystkich komentarzy pod postem @GET("/comments") fun getCommentsForPost(@Query("postId") postId: Int): Call<List<Comment>> //pobranie wszystkich profili @GET("/profile") fun getProfileInfo(): Call<List<Profile>> } Stworzenie zapytań do serwera W poniższej Activity pokazuję w jaki sposób wykonać requesty do serwera oraz jak obsłużyć odpowiedzi class MainActivity : AppCompatActivity() { private lateinit var restApi: RestAPI private var profileList = listOf<Profile>() private var posts = listOf<Post>() private var comments = listOf<Comment>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //gson służy do zamiany obiektów na json i jsonów na obiekty val gson = GsonBuilder() .setLenient() .create() // okHttpClient - klient HTTP z którego korzysta retrofit val okHttpClient = OkHttpClient.Builder().build() // stworzenie obiektu retrofit z konfiguracją val retrofit = Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create(gson)) .baseUrl("localhost:3000") .client(okHttpClient) .build() // stworzenie implementacji interfejsu RestApi restApi = retrofit.create(RestAPI::class.java) // Wykonywanie requestów restApi.getProfileInfo().enqueue(ProfileInfoResponseHandler()) //uproszczenie - wiem że dla takiego autora istnieją posty restApi.getPostsByAuthor("typicode").enqueue(PostResponseHandler()) //uproszczenie - wiem że komentarze istnieją dla postu o id 1 restApi.getCommentsForPost(1).enqueue(CommentsResponseHandler()) } private inner class ProfileInfoResponseHandler : Callback<List<Profile>> { override fun onFailure(call: Call<List<Profile>>, t: Throwable) { //co zrobić gdy coś pójdzie nie tak } override fun onResponse(call: Call<List<Profile>>, response: Response<List<Profile>>) { val body = response.body() ?: return profileList = body } } private inner class PostResponseHandler : Callback<List<Post>> { override fun onFailure(call: Call<List<Post>>, t: Throwable) { //co zrobić gdy coś pójdzie nie tak } override fun onResponse(call: Call<List<Post>>, response: Response<List<Post>>) { val body = response.body() ?: return posts = body } } private inner class CommentsResponseHandler : Callback<List<Comment>> { override fun onFailure(call: Call<List<Comment>>, t: Throwable) { //co zrobić gdy coś pójdzie nie tak } override fun onResponse(call: Call<List<Comment>>, response: Response<List<Comment>>) { val body = response.body() ?: return comments = body } } } Każde zapytanie wykonuje się asynchronicznie. Dlatego też należy stworzyć Handlery które będą oczekiwać odpowiedzi. Tutaj mamy trzy handlery które robią w sumie to samo. Są to: ProfileInfoResponseHandler, PostResponseHandler oraz CommentsResponseHandler. Każdy z nich implementuje dwie metody:onFailure - wykona się gdy wystąpi jakiś błąd np. serwer zwróci kod 500,onResponse - kiedy wszystko pójdzie zgodnie z planem i serwer zwróci odpowiedni response. Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach