iT邦幫忙

2021 iThome 鐵人賽

DAY 20
0
Mobile Development

Android 新手入門學習系列 第 20

Day20 Android - Retrofit(Get)

今天主要要來提提Retrofit,Retrofit主要透過interface連線串接以取得資料,像是取json、xml等的資料,待會會使用https://jsonplaceholder.typicode.com/posts 這邊的json資料來實作,那麼就開始今天的主題。
首先先加入依賴至gradle(app)/dependcies中。

依賴

    //retrofit資源
    implementation 'com.squareup.retrofit2:retrofit:2.7.2'
    //gson轉換器
    implementation 'com.squareup.retrofit2:converter-gson:2.7.2'

接著需要在manifest.xml中加入網路的權限。

權限

<uses-permission android:name="android.permission.INTERNET" />

依賴、權限沒加入的話寫到後面會跑錯誤,(permission之類的錯誤,或者是沒辦法import retrofit2的資源)。


添加完依賴、權限後,接下來的設計主要分為三大類:Model資料、Interface連線接口、Manager連線基底,那麼就先由Model資料的部分開始提。

Model資料

Model的職責主要在定義有什麼資料、並透過從Manager->interface取得資料,那麼首先就new一個java檔(我這邊取作Posts),接著看到https://jsonplaceholder.typicode.com/posts/1 這個網址中,主要有四筆資料(userId、Id、title、body),接著按照他的型態就可以設計出:

public class posts {
//定義有什麼資料(型態要注意)
    private int userId;
    private int Id;
    private String title;
    private String body;
    //從manager->interface使用call後,使this(這邊)定義的資料=取到的資料
    public posts(int userId,int Id,String title,String body){
        this.userId=userId;
        this.Id=Id;
        this.title=title;
        this.body=body;
    }
    //這邊是我們熟稱的getter、setter,可用於其他class的資料取得或處理
    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;
    }
}

model大約上是這樣子,而我推薦一個很方便的plugin(套件),它可以快速幫你把gson的資料轉成model。


首先先點file/setting然後找到plugins。
https://ithelp.ithome.com.tw/upload/images/20210901/20139259ACAF6FrlgV.png
找到plugins後,上方搜尋欄輸入GsonFormatPlus,可以找到套件,如果沒安裝過會顯示是Install的綠色按鈕,那麼就進行Install的動作,完了之後它會變成灰色的Installed。
https://ithelp.ithome.com.tw/upload/images/20210901/20139259m60vGtOqk5.png


那怎麼做使用呢?首先先回到你原先新創建好的model檔中,我的大約是長這樣:

//什麼都沒有,空空如也
public class posts {

}

接著在posts內按右鍵後->選擇Generate->選擇剛剛載的plugin(GsonFormatPlus)。
如圖:
https://ithelp.ithome.com.tw/upload/images/20210901/20139259haxkJGrXcq.png


https://ithelp.ithome.com.tw/upload/images/20210901/20139259lh4vV8OLjV.png

接著應該會看到下面的畫面。
https://ithelp.ithome.com.tw/upload/images/20210901/201392595wkRi9ZWlm.png

點擊Setting,改成如下的選項(最後的也可以改成other)後點OK。
https://ithelp.ithome.com.tw/upload/images/20210901/20139259G23Ur2U8Ks.png

接著就貼上https://jsonplaceholder.typicode.com/posts/1 這個網址的資料點OK。
https://ithelp.ithome.com.tw/upload/images/20210901/20139259SKkYJVcoO8.png

轉換成功後點OK就完成了model的資料定義及getter、setter的部分。
https://ithelp.ithome.com.tw/upload/images/20210901/20139259MJusSV6rzz.png

接著就加上到時要放的東西到這個model。

//從manager->interface使用call後,使this(這邊)定義的資料=取到的資料
public posts(int userId,int Id,String title,String body){
        this.userId=userId;
        this.Id=Id;
        this.title=title;
        this.body=body;
    }

Interface接口

首先在資料夾右鍵new一個Java Class,然後選Interface(它預設都是java,要自己改型態成interface)。
https://ithelp.ithome.com.tw/upload/images/20210901/20139259hMznzI5M1m.png
在這裡可以定義GET、POST方法。

//需要import的東西,如果是紅字則需要檢查gradle有沒有加入依賴
import retrofit2.Call;
import retrofit2.http.GET;

public interface posts_interface {
    @GET("posts/1")// posts/1:posts的第一筆資料路徑
    Call<posts> getpost();//取得連線後的回傳資料給posts物件,後者getpost()為此連線的方法名稱
    @GET("posts")//posts多筆資料的路徑 用List包
    Call<List<posts>> getposts();//取得連線後的多筆回傳資料給posts物件並包裝成List,getPosts()為此連線的方法名稱
}

當然還有使用Select from或是什麼@Query的部分,但我目前還沒有使用到,這邊大約都是GET網址的後綴部分,前面都是一個固定的url,接著提manager(連線基底)的部分。


Manager

//連線基底
public class posts_manager {
    //mInstance為連線轉換(Builder)的物件
    private static posts_manager mInstance = new posts_manager();
    
    private posts_interface Posts_interface;

    private posts_manager() {
        //使用Builder,Url為要連到的網址,之後addConverterFactory的部分就是加入Gson的轉換器,然後建立在這個retrofit的物件
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://jsonplaceholder.typicode.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        Posts_interface = retrofit.create(posts_interface.class);
    }
    //回傳Builder方法
    public static posts_manager getInstance() {
        return mInstance;
    }
    
    //回傳interface的內容(可以使用裡面定義的連線名稱進行連線)
    public posts_interface getAPI() {
        return Posts_interface;
    }
}

最後在主程式設計:

MainActivity

public class MainActivity extends AppCompatActivity {
    posts_interface posts;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //getInstance()取得Builder的轉換方法.getAPI()取得interface的物件內容
        posts=posts_manager.getInstance().getAPI();
        //建立call連線,為posts內的getposts(連線名稱)
        Call<List<Posts>> call = posts.getposts();
        //進行連線
        call.enqueue(new Callback<List<Posts>>() {
            @Override
            // Response為回傳的資料
            public void onResponse(Call<List<Posts>> call, Response<List<Posts>> response) {
                //連線成功做的事,資料在response.body()內,透過getter可將資料取得
                //此處定義物件item,for從第一筆run到最後一筆的資料進行Log
                for(Posts item : response.body()) {
                    Log.d("Data","Response call: "+response.code());
                    Log.d("Data","id :"+item.getId());
                    Log.d("Data","Userid :"+item.getUserId());
                    Log.d("Data","title :"+item.getTitle());
                    Log.d("Data","body :"+item.getBody());
                }
            }

            @Override
            public void onFailure(Call<List<Posts>> call, Throwable t) {
                //連線失敗做的事
                Log.d("Data","Failed!");
            }
        });
    }
}

成果

因為資料有點多,我就只放幾筆Log出來的部分:
https://ithelp.ithome.com.tw/upload/images/20210901/20139259Kw5Gfrfzee.png
大約是這樣子,然後她的狀態碼都是200,那麼明天來提提Post的部分。


上一篇
Day19 Android - NestedScrollView
下一篇
Day21 Android - Retrofit(Post)
系列文
Android 新手入門學習30

尚未有邦友留言

立即登入留言