今天的文章會偏長,這邊簡單的列舉幾個要點:
/posts
API接取建立)/users
API接取建立)retrofit
是一個接API資料的第三方開發的套件,使用之前需要做一些前置建立。
retrofit
依賴以及OKHTTP3
依賴Sync now
。 implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation("com.squareup.okhttp3:okhttp:4.10.0")
<!-- 宣告連線網路-->
<uses-permission android:name="android.permission.INTERNET" />
以上前置建立完成後就是程式碼的撰寫了
這邊我是創立了幾個檔案:
APIResponse
APIService
SiteManager
Activity
(這邊不用特別建立)這個部分目前來說不是很需要,有興趣的可以到Postman網站下載postman應用程式。
Postman對於抓取API資料十分方便,特別是有要輸入請求參數的時候不用在打一些符號。
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
},
{
"userId": 1,
"id": 2,
"title": "qui est esse",
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
},
....以下省略
{
"userId": 10,
"id": 99,
"title": "temporibus sit alias delectus eligendi possimus magni",
"body": "quo deleniti praesentium dicta non quod\naut est molestias\nmolestias et officia quis nihil\nitaque dolorem quia"
},
{
"userId": 10,
"id": 100,
"title": "at nam consequatur ea labore ea harum",
"body": "cupiditate quo est a modi nesciunt soluta\nipsa voluptas error itaque dicta in\nautem qui minus magnam et distinctio eum\naccusamus ratione error aut"
}
]
接下來就是建立相關程式碼的部分了
--
這邊參數的資料型態有一個識別方法,如果參數後方沒有""
框起來的是int型態、反之就是String型態。
p.s.:參數全部設定String型態也是可以過。
private int userId;
private int id;
private String title;
private String body;
//getter & setter
public int getUserId () {
return userId;
}
public void setUserId (int userId) {
this.userId = userId;
}
public int getId () {
return id;
}
public void setId (int id) {
this.id = id;
}
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;
}
這邊我是在外面建立一個java檔並且寫在那邊。
baseUrl("網址")
,後面會連接APIService的部分。addConverterFactory(GsonConverterFactory.create())
:這個部分是轉成Gson資料。build()
:建立。 // 以Singleton模式建立
private static SiteManager mInstance = new SiteManager ();
private APIService myAPIService;
private SiteManager () {
// 設置baseUrl即要連的網站,addConverterFactory用Gson作為資料處理Converter
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://jsonplaceholder.typicode.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
myAPIService = retrofit.create(APIService.class);
}
public static SiteManager getInstance() {
return mInstance;
}
public APIService getAPI() {
return myAPIService;
}
GET
、POST
、PUT
、DELETE
這些。[]
括起來,如下圖的第一行,如果有被括起來就是一個陣列型態,在下方Call<T>
裡面就必須再加一個List<T>
或是ArrayList<T>
,形成最後的Call<List<T>>
。public interface APIService {
@GET("posts")
Call<List<APIResponse>> response();
}
public void GetFakeAPI(){
Call<List<APIResponse>> call = apiService.response ();
call.enqueue (new Callback<List<APIResponse>> () {
@Override
public void onResponse (Call<List<APIResponse>> call, Response<List<APIResponse>> response) {
for (int i = 0;i<response.body ().size ();i++){
//利用For迴圈把所有存在的資料印出來。
Log.e ("TAG", "userid: "+response.body ().get (i).getUserId ());
Log.e ("TAG", "ID: "+response.body ().get (i).getId ());
Log.e ("TAG", "title: "+response.body ().get (i).getTitle ());
Log.e ("TAG", "body: "+response.body ().get (i).getBody ());
}
Log.e ("TAG", "size: "+response.body ().size () );
}
@Override
public void onFailure (Call<List<APIResponse>> call, Throwable t) {
Log.e ("TAG", "onFailure: " );
}
});
}
注意看的話可以看到上面設定的參數所接收到的數據。
有時候會看到一個Clas內不只有包參數還有再包另一個Class的情況,如下圖。
這時參數建立的時候就必須再創另一個class,名稱也是要與上面名稱相符。
例如:address.java
、geo.java
。
創立完之後其他參數與上面的創建方式一樣,這邊就已最外層的class做說明。
private address address;
:這就可以把address拉進來這個class了。public class UsersResponse {
private int id;
private String name;
private String username;
private String email;
private address address;
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 getUsername () {
return username;
}
public void setUsername (String username) {
this.username = username;
}
public String getEmail () {
return email;
}
public void setEmail (String email) {
this.email = email;
}
public com.example.retrofit_test_project.address getAddress () {
return address;
}
public void setAddress (com.example.retrofit_test_project.address address) {
this.address = address;
}
}
public class address {
private String street;
private String suite;
private String city;
private String zipcode;
private geo geo;
public String getStreet () {
return street;
}
public void setStreet (String street) {
this.street = street;
}
public String getSuite () {
return suite;
}
public void setSuite (String suite) {
this.suite = suite;
}
public String getCity () {
return city;
}
public void setCity (String city) {
this.city = city;
}
public String getZipcode () {
return zipcode;
}
public void setZipcode (String zipcode) {
this.zipcode = zipcode;
}
public com.example.retrofit_test_project.usersapicatch.geo getGeo () {
return geo;
}
public void setGeo (com.example.retrofit_test_project.usersapicatch.geo geo) {
this.geo = geo;
}
}
public class geo {
private String lat;
private String lng;
public String getLat () {
return lat;
}
public void setLat (String lat) {
this.lat = lat;
}
public String getLng () {
return lng;
}
public void setLng (String lng) {
this.lng = lng;
}
}
@GET("users")
Call<List<UsersResponse>> userresponse();
這邊目前的建立方式與上方相同,在包了其他的Class要呼叫也是繼續走下去而已。
例如我要抓到Geo的Lng資料就是如下的寫法,因為geo又是被address包住的Class。
Log.e ("TAG", "Address_Geo_Lng: "+response.body ().get (i).getAddress ().getGeo ().getLng ());
public void GetUsersInfomation(){
Call<List<UsersResponse>> calluser = apiService.userresponse ();
calluser.enqueue (new Callback<List<UsersResponse>> () {
@Override
public void onResponse (Call<List<UsersResponse>> call, Response<List<UsersResponse>> response) {
for (int i = 0;i<response.body ().size ();i++){
Log.e ("TAG", "ID: "+response.body ().get (i).getId () );
Log.e ("TAG", "Name: "+response.body ().get (i).getName () );
Log.e ("TAG", "UserName: "+response.body ().get (i).getUsername () );
Log.e ("TAG", "Email: "+response.body ().get (i).getEmail () );
Log.e ("TAG", "Address_Street: "+response.body ().get (i).getAddress ().getStreet () );
Log.e ("TAG", "Address_Suite: "+response.body ().get (i).getAddress ().getSuite () );
Log.e ("TAG", "Address_City: "+response.body ().get (i).getAddress ().getCity ());
Log.e ("TAG", "Address_Zipcode: "+response.body ().get (i).getAddress ().getZipcode ());
Log.e ("TAG", "Address_Geo_Lat: "+response.body ().get (i).getAddress ().getGeo ().getLat ());
Log.e ("TAG", "Address_Geo_Lng: "+response.body ().get (i).getAddress ().getGeo ().getLng ());
}
Log.e ("TAG", "Size: "+response.body ().size () );
}
@Override
public void onFailure (Call<List<UsersResponse>> call, Throwable t) {
Log.e ("TAG", "onFailure: ");
}
});
}
APIService apiService;
SiteManager loginSiteManager;
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
apiService = loginSiteManager.getInstance ().getAPI ();
GetFakeAPI ();
GetUsersInfomation ();
}