iT邦幫忙

2022 iThome 鐵人賽

DAY 23
0
Mobile Development

Android Studio 30天學習系列 第 23

Android Studio 30天學習-DAY23_Retrofit基本設置

  • 分享至 

  • xImage
  •  

Retrofit簡單操作以及結合PostMan

今天的文章會偏長,這邊簡單的列舉幾個要點:

  1. dependencies依賴建立
  2. 建立檔案
  3. 參數建立(/postsAPI接取建立)
  4. 建立連線
  5. 副程式撰寫
  6. 進階的參數建立方式(/usersAPI接取建立)

retrofit是一個接API資料的第三方開發的套件,使用之前需要做一些前置建立。

dependencies依賴

  • 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")
  • AndroidManifest新增網路權限
    宣告在Application底下。
    <!--    宣告連線網路-->
    <uses-permission android:name="android.permission.INTERNET" />

以上前置建立完成後就是程式碼的撰寫了

建立Java檔案

這邊我是創立了幾個檔案:

  1. APIResponse
    • 這是用來建立Postman所看到的回覆參數,等等會先說明postman的基本操作。
  2. APIService
  3. SiteManager
  4. Activity(這邊不用特別建立)

postman查詢要抓取的資料

這個部分目前來說不是很需要,有興趣的可以到Postman網站下載postman應用程式。
Postman對於抓取API資料十分方便,特別是有要輸入請求參數的時候不用在打一些符號。

  • 我這邊要抓取的資料在下方貼上的這串網址中,直接在網頁點開也是可以看到Json檔的,我這邊就在postman進行操作。
    (https://jsonplaceholder.typicode.com/posts)
    • postman開啟
    • 網頁開啟
  • 這邊可以看到獲取到的Json資料。
[
    {
        "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"
    }
]
  • 在這邊可以看到我們需要建立幾筆參數:
    1. userId
    2. id
    3. title
    4. body
    • 注意:以上參數名稱建立與這裡的名稱必須一致

接下來就是建立相關程式碼的部分了

--

參數建立

這邊參數的資料型態有一個識別方法,如果參數後方沒有""框起來的是int型態、反之就是String型態。
p.s.:參數全部設定String型態也是可以過。

  • APIResponse.java
    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檔並且寫在那邊。

  • SiteManager.java
    這邊可以看到我又有把APIService引進來,這邊的部分在後面會連著說。
    • 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;
    }
  • APIService.java
    這個要以Interface方式去建立,然後這部分建立的是我們要做的是GET、POST、DELETE、PUT...等等的操作方式,在postman上面是這樣。
  • 最常見的就是GETPOSTPUTDELETE這些。
  • 這邊需要注意一個要點
    • json資料的外層有沒有被[]括起來,如下圖的第一行,如果有被括起來就是一個陣列型態,在下方Call<T>裡面就必須再加一個List<T>或是ArrayList<T>,形成最後的Call<List<T>>
public interface APIService {

    @GET("posts")
    Call<List<APIResponse>> response();
}

MainActivty程式

  • 接收post副程式
    • onResponse是如果接收成功的話會執行當中的事件。
    • onFailure是接收失敗的時候會執行。
    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: " );
            }
        });
    }

/posts結果顯示

注意看的話可以看到上面設定的參數所接收到的數據。

  • id = 1
    • logcat顯示畫面
    • postman資料
  • id = 100
    • logcat顯示
    • postman資料

參數建立(進階用法)

有時候會看到一個Clas內不只有包參數還有再包另一個Class的情況,如下圖。

這時參數建立的時候就必須再創另一個class,名稱也是要與上面名稱相符。
例如:address.javageo.java

創立完之後其他參數與上面的創建方式一樣,這邊就已最外層的class做說明。

  • 把已創立完成的address.java套用進來。
    • private address address;:這就可以把address拉進來這個class了。
  • UsersResponse.java(最外層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;
    }
}
  • address.java(第二層Class)
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;
    }
}
  • geo.java(最後一層Class)
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();

MainActivity

這邊目前的建立方式與上方相同,在包了其他的Class要呼叫也是繼續走下去而已。
例如我要抓到Geo的Lng資料就是如下的寫法,因為geo又是被address包住的Class。

 Log.e ("TAG", "Address_Geo_Lng: "+response.body ().get (i).getAddress ().getGeo ().getLng ());
  • GetUsersInfomation副程式
    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 ();
    }

以上是今天的Retrofit基本設置。


上一篇
Android Studio 30天學習-DAY22_Android_ROOM的基本練習
下一篇
Android Studio 30天學習-DAY24_Rxjava基本建立學習
系列文
Android Studio 30天學習30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言