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的部分。


<<:  [Day-26] math函式库(二)

>>:  Unity与Photon的新手相遇旅途 | Day20-Photon连线基本设定

D 语言和你 SAY HELLO!!

第十七天 各位点进来的朋友,你们好阿 小的不才只能做这个系列的文章,但还是希望分享给点进来的朋友,知...

Day5 - numpy(4)ndarray的运算及全域函式

ndarray的运算: 相同大小的阵列之间进行运算,称作为 向量化 意味着同时对整批的资料一起做运算...

Day 14:专案02 - PTT C_chat版爬虫01 | 爬虫简介、request和response、Requests

⚠行前通知 先前已经学过Python但想学爬虫的人可以回来罗~ 从今天起就开始大家最期待的网页爬虫的...

[机派X] Day 11 - 让我们拆了这台无人机

引言 今天是机派X系列文章的第十一天。 昨天很寒酸的简介无人机,今天会从单一零件的角度一一将无人机的...

目前销售流程遇到什麽问题?

在探讨这个问题之前,先来分享我们目前的销售流程 搜集名单 透过脸书投放名单型广告,或是 Google...