Retrofit
Retrofit is simple HTTP Client Android and Java by square.
Simple use and follow callback style, compare to Async task, code becomes shorter.
Server side preparation
In this time, I prepared following API (on local) by golang (I just put the codes on the bottom of this entry)
GET : http://localhost:8000/users/{id} -> Return one user object by json
GET : http://localhost:8000/list -> Return user list object
POST : http://localhost:8000/post Body {id: “ss”} -> Return success object {success : true}
How to use retrofit
Add dependencies to build.gradle
build.gradle
android { compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } } dependencies { implementation 'com.squareup.retrofit2:retrofit:2.8.1' implementation 'com.squareup.retrofit2:converter-gson:2.8.1' }
converter-gson is json -> object converter powered by google
NetworkService.kt
This is Service interface codes. To use Retrofit, we need to prepare service (definition of API call)
package com.daiji110.retrofitsample.service import com.daiji110.retrofitsample.model.Success import com.daiji110.retrofitsample.model.User import retrofit2.Call import retrofit2.http.* interface NetworkService { @GET("/users/{id}") fun getUser(@Path("id") id: String) : Call<User> @GET("/list") fun getList() : Call<List<User>> @Headers( "User-Agent:Retrofit-Sample-App") @POST("post") fun post(@Body id: String) : Call<Success> }
User.kt
This is response model. Retrofit converts json to Object using converter
data class User(val id: String, val name: String, val age: Int)
Success.kt
data class Success(val success: Boolean)
MainActivity.kt
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val retrofit : Retrofit = Retrofit.Builder() .baseUrl("http://10.0.2.2:8000/") .addConverterFactory(GsonConverterFactory.create()) .build() val service : NetworkService = retrofit.create(NetworkService::class.java) // Sync : Need to call not main thread /* val response = service.getUser("1").execute() if (response.isSuccessful) { Log.d("Sync", response.body().toString()) } */ // Async service.getUser("1").enqueue(object : Callback<User> { override fun onFailure(call: Call<User>, t: Throwable) { Log.w("Error", t.message) } override fun onResponse(call: Call<User>, response: Response<User>) { Log.d("ASync", response.body().toString()) response.body()?.let { Log.d("Name", it.name) Log.d("Age", it.age.toString()) Log.d("ID", it.id.toString()) } } }) // Async list return service.getList().enqueue(object: Callback<List<User>> { override fun onFailure(call: Call<List<User>>, t: Throwable) { Log.w("Error", t.message) } override fun onResponse(call: Call<List<User>>, response: Response<List<User>>) { response.body()?.let { it.forEach { Log.d("Name", it.name) Log.d("Age", it.age.toString()) Log.d("ID", it.id.toString()) } } } }) // Post service.post("33").enqueue(object: Callback<Success> { override fun onFailure(call: Call<Success>, t: Throwable) { Log.w("Error", t.message) } override fun onResponse(call: Call<Success>, response: Response<Success>) { response.body()?.let { Log.d("Res", it.toString()) } } }) } }
Golang code
This is server side codes to support this.
I don’t explain about this details in this time
package main import ( "encoding/json" "fmt" "io/ioutil" "net/http" "github.com/gorilla/mux" ) type User struct { Name string `json:"name"` Age int `json:"age"` ID string `json:"id"` } type Res struct { Success bool `json:"success"` } /* * Routing */ func users(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["id"] person := User{ Name: "Jiro", Age: 18, ID: id, } json.NewEncoder(w).Encode(person) } func list(w http.ResponseWriter, r *http.Request) { user1 := User{ Name: "Taro", Age: 18, ID: "111111", } user2 := User{ Name: "Jiro", Age: 30, ID: "222222", } user3 := User{ Name: "Santa", Age: 55, ID: "333333", } var s []User s = append(s, user1, user2, user3) json.NewEncoder(w).Encode(s) } func POSTHandle(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) defer r.Body.Close() body, err := ioutil.ReadAll(r.Body) fmt.Println(body) res := Res{ Success: true, } if err != nil { res.Success = false } json.NewEncoder(w).Encode(res) } func main() { router := mux.NewRouter() router.HandleFunc("/users/{id}", users) router.HandleFunc("/list", list) router.HandleFunc("/post", POSTHandle).Methods("POST") http.ListenAndServe(":8000", router) }
コメント