Android框架第(五)篇---Retrofit基本使用

**版權(quán)聲明:本文為小斑馬偉原創(chuàng)文章徙歼,轉(zhuǎn)載請(qǐng)注明出處!


Retrofit:(A type-safe HTTP client for Android and Java)通過(guò)注解的方式描述HTTP請(qǐng)求,底層由OKHttp實(shí)現(xiàn) 看成是對(duì)OKHttp的一次封裝犁河,采用注解方式來(lái)描述HTTP請(qǐng)求。非常適合RESTFul風(fēng)格的網(wǎng)絡(luò)請(qǐng)求,目前版本2.0.0.

一魄梯、 RESTful

REST:是 “REpresentational State TRransfer” 的縮寫(xiě)桨螺,即"表現(xiàn)層狀態(tài)轉(zhuǎn)換"。表現(xiàn)層:網(wǎng)絡(luò)上資源的變現(xiàn)形式(資源:是網(wǎng)絡(luò)上的一個(gè)實(shí)體酿秸,或者說(shuō)網(wǎng)絡(luò)上的具體信息灭翔,可以是一段文本、一張圖片辣苏、一首歌曲肝箱、一種服務(wù)∠◇總之就是具體的實(shí)在煌张。我們可以用一個(gè)URI,統(tǒng)一定向符指向它退客。每種資源對(duì)應(yīng)一個(gè)特定的URI骏融,要獲取它的資源链嘀,就要訪問(wèn)它的URI。因此URI就成為每一個(gè)資源的地址档玻,或者獨(dú)一為二識(shí)別符怀泊。我們常說(shuō)的上網(wǎng)就是互聯(lián)網(wǎng)上的資源的互動(dòng),調(diào)用它的URI窃肠。表現(xiàn)層就是網(wǎng)絡(luò)資源的一種表現(xiàn)形式包个。資源是實(shí)體信息,它可以多種外在的形式冤留,我們把資源具體呈現(xiàn)出的信息碧囊,我們叫它表現(xiàn)層。比如文本可以用txt形式表現(xiàn)纤怒,也可以用html形式表現(xiàn)糯而。URI只代表資源的實(shí)體。不代表資源的形式泊窘。嚴(yán)格上來(lái)說(shuō)熄驼,某些文件的后綴名是可以不需要的,因?yàn)樗潜硎靖袷胶姹硎颈憩F(xiàn)層的范疇瓜贾。而URI只表示資源的位置。它的具體表現(xiàn)形式携悯,應(yīng)該在HTTP請(qǐng)求的頭部信息中祭芦,用Content-Type和Obser形式指定)。
狀態(tài)轉(zhuǎn)換:客戶端通過(guò)某種手段使得服務(wù)器上資源發(fā)生變化憔鬼,訪問(wèn)一個(gè)網(wǎng)站龟劲,肯定會(huì)涉及到客戶端和服務(wù)端互動(dòng)過(guò)程,在這個(gè)過(guò)程中轴或,勢(shì)必涉及到數(shù)據(jù)和狀態(tài)的轉(zhuǎn)換昌跌,互聯(lián)網(wǎng)的協(xié)議是HTTP狀態(tài)的協(xié)議,這就意味著所有的狀態(tài)必須保存在服務(wù)器端照雁,如果客戶端要操作數(shù)據(jù)蚕愤,就必須通過(guò)某種手段,讓服務(wù)器端發(fā)生狀態(tài)轉(zhuǎn)換饺蚊。而這種轉(zhuǎn)化是建立在表現(xiàn)層上的萍诱,所以就是表現(xiàn)層的狀態(tài)轉(zhuǎn)換。而客戶端使用的手段卸勺,只能是HTTP的協(xié)議,具體的說(shuō)就是HTPP里面具體四個(gè)操作符的動(dòng)詞烫扼,GET POST PATH DELETE曙求。

二、 RESRful架構(gòu)
  • 1、每一個(gè)URI代表一種資源悟狱,而不是對(duì)資源的一種操作静浴。
  • 2、客戶端和服務(wù)器之間挤渐,傳遞這種資源的某種表現(xiàn)層苹享。
  • 3、客戶端通過(guò)HTTP動(dòng)作浴麻,對(duì)服務(wù)端資源進(jìn)行操作得问。
三、Retrofit引入

compile’com.squareup.retrofit2:retrofit:2.0.1'

四软免、Retrofit請(qǐng)求網(wǎng)絡(luò)流程*

定義一個(gè)URL:http://192.168.31.242:8080/android/user/users

  • 3.1 定義一個(gè)接口對(duì)象

     public interface IUserInfo {
        GET("users")
        Call<List<User>> getUsers();
    }
    
  • 3.2 構(gòu)造Retrofit對(duì)象

    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://192.168.31.242:8080/android/user/")
        .addConverterFactory(GsonConverterFactory.create()) //json格式轉(zhuǎn)換器
        .build();
    
  • 3.3 拿到接口對(duì)象的實(shí)例

    IUserInfo userInfo = retrofit.create(IUserInfo.class);
    
  • 4.3由接口對(duì)象生成call對(duì)象宫纬,并執(zhí)行網(wǎng)絡(luò)請(qǐng)求

    Call<List<User>> call = userInfo.getUsers();
    call.enqueue(new Callback<List<User>>() {
         @Override
         public void onResponse(Call<List<User>> call, Response<List<User>> response)
         {
            Log.i(TAG,"onResponse:"+response.body()+"");
         }
         @Override
         public void onFailuse(Call<List<User>>call, Throwable t){}
         });
    
五、Retrofit常用注解 - @Path

1.用于訪問(wèn)zhangsan的信息
http://192.168.1.102:8080/android/user/users/zhangsan
2.用于訪問(wèn)lisi的信息
http://192.168.1.102:8080/android/user/users/lisi
這種風(fēng)格URL只是符合RESTful的設(shè)計(jì)風(fēng)格的膏萧,URL只表示資源信息漓骚,因?yàn)槲覀冊(cè)谶@個(gè)URL看不到任何的網(wǎng)絡(luò)信息的請(qǐng)求。這個(gè)請(qǐng)求在我們的html方法中來(lái)執(zhí)行榛泛。這種的類型的API就是RESRful的API蝌蹂。

public interface IUserInfo {
    @GET("{username}") //占位符 通過(guò)傳遞來(lái)到參數(shù)進(jìn)行替換
    Call<User> getUser(@Path("username") String username);
}

//Call<User> call = userInfo.getUser("zhangsan")
 Call<User> call = userInfo.getUser("lisi");                              
五、Retrofit常用注解 - @Query

1.用于訪問(wèn)zhangsan的信息
http://192.168.1.102:8080/android/user/users/?name=zhangsan
2.用于訪問(wèn)lisi的信息
http://192.168.1.102:8080/android/user/users/?name=lisi

public interface IUserInfo {
    GET("users")
    Call<List<User>> getUsersByName(@Query("name") String name); //定義一個(gè)key:name 后面?zhèn)鬟f來(lái)的參數(shù)曹锨。通過(guò)Query注解來(lái)拼接孤个,把key:name和后面?zhèn)鬟f來(lái)的name拼接成一個(gè)鍵值對(duì)。然后把這個(gè)鍵值對(duì)加到URL后面艘希。
 }
//Call<List<User>> call = userInfo.getUserByName("zhangsan");
 Call<List<User>> call = userInfo.getUserByName("lisi");

定義一個(gè)key:name 后面?zhèn)鬟f來(lái)的參數(shù)硼身。通過(guò)Query注解來(lái)拼接,把key:name和后面?zhèn)鬟f來(lái)的name拼接成一個(gè)鍵值對(duì)覆享。然后把這個(gè)鍵值對(duì)加到URL后面佳遂。

六、Retrofit常用注解 - @Body(一般用于POST)請(qǐng)求
public interface IUserInfo {
   @POST("users")
   Call<List<User>> addUser(@Body User user);
}

Call<User> call = userInfo.addUser(new User(236,"zhangsan")); //把一個(gè)json對(duì)象的字符串發(fā)送給服務(wù)器的

通過(guò)POST定義是一個(gè)POST請(qǐng)求撒顿,POST后面的請(qǐng)求的值和baseUrl組成一個(gè)完成的請(qǐng)求的URL的路徑丑罪,然后定義了一個(gè)方法addUser添加用戶,通過(guò)Body注解在調(diào)用這個(gè)方法的時(shí)候凤壁,只需要傳遞一個(gè)對(duì)象吩屹。這個(gè)注解自動(dòng)把這個(gè)對(duì)象轉(zhuǎn)換成json字符串。添加到我們網(wǎng)絡(luò)請(qǐng)求的Body中拧抖,發(fā)給服務(wù)器煤搜。定義這個(gè)接口后,如果我們添加一個(gè)張三唧席,通過(guò)userInfo事例的addUser方法擦盾,傳遞來(lái)一個(gè)User就OK嘲驾。

七、Retrofit常用注解 - @FormUrlEncoded 表示以表單的形式傳遞鍵值對(duì)迹卢。
public interface IUserInfo {
    @POST("register")
    @FormUrlEncoded
    Call<User> register(@Field("userid") String userid, @Field("username") String username);
}

Call<User> call = userInfo.register("123","zhangsan"); //FormUrlEncoded注解自動(dòng)的將123和zhangsan 以及userid和username拼接成鍵值對(duì)的方式辽故,發(fā)送給服務(wù)器。
八腐碱、Retrofit常用注解 - @Multipart (表示單文件上傳)
public interface IUserInfo {
    @Multipart //多個(gè)Part
    @POST("register")
    Call<User> register(@Part MultipartBody.Part icon, @Part("userid") RequestBody userid); //1.part 表示上傳的文件誊垢,第二個(gè)part表示是一個(gè)鍵值對(duì),表示用戶的ID
}

發(fā)起GET請(qǐng)求

private void getRequest() {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(baseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    IGetInfos getInfos = retrofit.create(IGetInfos.class);

    Call<ResponseCategory> call = getInfos.getCategories();
    call.enqueue(new Callback<ResponseCategory>() {
        @Override
        public void onResponse(Call<ResponseCategory> call, Response<ResponseCategory> response) {
            ResponseCategory responseCategory = response.body();
            Log.i("data","onResponse() success !!");
        }

        @Override
        public void onFailure(Call<ResponseCategory> call, Throwable t) {

        }
    });
}

private String baseUrl = "http://35.185.149.228";

private class ResponseCategory {

    public int status;

    public List<CategoryMode> date;

    public class CategoryMode {
        public int id;
        public String name;
    }
}
private interface  IGetInfos {
    @GET("user/get-big-direction")
    Call<ResponseCategory> getCategories();
}

發(fā)起POST上傳鍵值對(duì)(登錄)

 private void postPairs() {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(baseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    IUserLogin userLogin = retrofit.create(IUserLogin.class);

    Call<RespLoginModel> call = userLogin.login("sda","233");
    call.enqueue(new Callback<RespLoginModel>() {
        @Override
        public void onResponse(Call<RespLoginModel> call, Response<RespLoginModel> response) {
            RespLoginModel responseCategory = response.body();
            Log.i("data","onResponse() success !!");
        }

        @Override
        public void onFailure(Call<RespLoginModel> call, Throwable t) {

        }
    });
}

public class RespLoginModel {
    public int status;
    public User data;

    public class User {
        private String id;
        private String username;
        private String avatar;
    }
}

public interface  IUserLogin{
    @POST("user/do-login")
    @FormUrlEncoded
    Call<RespLoginModel> login(@Field("login-username") String username,@Field("login-password") String password);
}

上傳文件

 private void upLoad() {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(baseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    IUpLoadIcon upLoadIcon = retrofit.create(IUpLoadIcon.class);

    File file = new File(Environment.getExternalStorageDirectory()+"ic_laucher.png");
    RequestBody photoBody = RequestBody.create(MediaType.parse("imge/png"),file);

    MultipartBody.Part phone = MultipartBody.Part.createFormData("uplaodImg[file]",file.getName(),photoBody);
    Call<RespUpLoadModel> call = upLoadIcon.upLoadIcon(phone);

    call.enqueue(new Callback<RespUpLoadModel>() {
        @Override
        public void onResponse(Call<RespUpLoadModel> call, Response<RespUpLoadModel> response) {
            RespUpLoadModel responseCategory = response.body();
            Log.i("data","onResponse() success !!");
        }

        @Override
        public void onFailure(Call<RespUpLoadModel> call, Throwable t) {

        }
    });
}

public class RespUpLoadModel {
    private int status;

    private Img data;

    private class Img {
        private String img_url;
    }
}

public interface  IUpLoadIcon {
    @POST("file/upload-img")
    @Multipart
   Call<RespUpLoadModel> upLoadIcon(@Part MultipartBody.Part phone);
}

Retrofit網(wǎng)絡(luò)請(qǐng)求:本質(zhì)上是OKHttp完成,而Retrofit僅負(fù)責(zé)網(wǎng)路請(qǐng)求的接口的封裝症见。實(shí)際上就是使用Retrofit的接口封裝我們請(qǐng)求的參數(shù)Hearder頭部喂走,URL信息等等,最后交給OKHttp來(lái)完成后續(xù)的網(wǎng)路請(qǐng)求操作筒饰。在服務(wù)端返回?cái)?shù)據(jù)給我們缴啡,OkHttp將原始的接口交給Retrofit。Retrofit根據(jù)用戶的需求對(duì)結(jié)果進(jìn)行不同類型的解析瓷们。
Retrofit進(jìn)行網(wǎng)絡(luò)請(qǐng)求的主要步驟:
1.創(chuàng)建描述網(wǎng)絡(luò)請(qǐng)求的接口
定義方法和相應(yīng)的注解:其內(nèi)部通過(guò)動(dòng)態(tài)代理的模式业栅,將我們接口和它的注解轉(zhuǎn)換成一個(gè)HTTP請(qǐng)求,最后再去執(zhí)行我們的HTTP請(qǐng)求谬晕。
接口里面的方法和參數(shù)碘裕,都必須要用注解的方式標(biāo)注,否者不標(biāo)注就會(huì)出錯(cuò)攒钳。
2.創(chuàng)建Retrofit實(shí)例
3.創(chuàng)建網(wǎng)絡(luò)請(qǐng)求接口實(shí)例并配置網(wǎng)絡(luò)請(qǐng)求參數(shù)
4.發(fā)送網(wǎng)絡(luò)請(qǐng)求(異步或者同步)
5.處理服務(wù)器返回的數(shù)據(jù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末帮孔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子不撑,更是在濱河造成了極大的恐慌文兢,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件焕檬,死亡現(xiàn)場(chǎng)離奇詭異姆坚,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)实愚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)兼呵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人腊敲,你說(shuō)我怎么就攤上這事击喂。” “怎么了碰辅?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵懂昂,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我没宾,道長(zhǎng)凌彬,這世上最難降的妖魔是什么潮尝? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮饿序,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘羹蚣。我一直安慰自己原探,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布顽素。 她就那樣靜靜地躺著咽弦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胁出。 梳的紋絲不亂的頭發(fā)上型型,一...
    開(kāi)封第一講書(shū)人閱讀 49,741評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音全蝶,去河邊找鬼闹蒜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛抑淫,可吹牛的內(nèi)容都是我干的绷落。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼始苇,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼砌烁!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起催式,我...
    開(kāi)封第一講書(shū)人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤函喉,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后荣月,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體管呵,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年喉童,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了撇寞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡堂氯,死狀恐怖蔑担,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情咽白,我是刑警寧澤啤握,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站晶框,受9級(jí)特大地震影響排抬,放射性物質(zhì)發(fā)生泄漏懂从。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一蹲蒲、第九天 我趴在偏房一處隱蔽的房頂上張望番甩。 院中可真熱鬧,春花似錦届搁、人聲如沸缘薛。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)宴胧。三九已至,卻和暖如春表锻,著一層夾襖步出監(jiān)牢的瞬間恕齐,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工瞬逊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留显歧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓确镊,卻偏偏與公主長(zhǎng)得像追迟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子骚腥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理敦间,服務(wù)發(fā)現(xiàn),斷路器束铭,智...
    卡卡羅2017閱讀 134,628評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,732評(píng)論 25 707
  • API定義規(guī)范 本規(guī)范設(shè)計(jì)基于如下使用場(chǎng)景: 請(qǐng)求頻率不是非常高:如果產(chǎn)品的使用周期內(nèi)請(qǐng)求頻率非常高廓块,建議使用雙通...
    有涯逐無(wú)涯閱讀 2,521評(píng)論 0 6
  • 本篇文章篇幅比較長(zhǎng),先來(lái)個(gè)思維導(dǎo)圖預(yù)覽一下契沫。 一带猴、概述 1.計(jì)算機(jī)網(wǎng)絡(luò)體系結(jié)構(gòu)分層 2.TCP/IP 通信傳輸流 ...
    滌生_Woo閱讀 54,968評(píng)論 24 557
  • 一:合作(美容院 婚慶 攝影 紋身 宗教 醫(yī)院/寵物店 銀行 金融 海外)等機(jī)構(gòu)合作 二:定位 名人明星官員 提供...
    光鋒容閱讀 498評(píng)論 0 0