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ù)??傊褪蔷唧w的實(shí)在。我們可以用一個(gè)URI,統(tǒng)一定向符指向它。每種資源對(duì)應(yīng)一個(gè)特定的URI,要獲取它的資源,就要訪(fǎng)問(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)樗潜硎靖袷?,表示表現(xiàn)層的范疇。而URI只表示資源的位置。它的具體表現(xiàn)形式,應(yīng)該在HTTP請(qǐng)求的頭部信息中,用Content-Type和Obser形式指定)。
狀態(tài)轉(zhuǎn)換:客戶(hù)端通過(guò)某種手段使得服務(wù)器上資源發(fā)生變化,訪(fǎng)問(wèn)一個(gè)網(wǎng)站,肯定會(huì)涉及到客戶(hù)端和服務(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ù)器端,如果客戶(hù)端要操作數(shù)據(jù),就必須通過(guò)某種手段,讓服務(wù)器端發(fā)生狀態(tài)轉(zhuǎn)換。而這種轉(zhuǎn)化是建立在表現(xiàn)層上的,所以就是表現(xiàn)層的狀態(tài)轉(zhuǎn)換。而客戶(hù)端使用的手段,只能是HTTP的協(xié)議,具體的說(shuō)就是HTPP里面具體四個(gè)操作符的動(dòng)詞,GET POST PATH DELETE。

二、 RESRful架構(gòu)
  • 1、每一個(gè)URI代表一種資源,而不是對(duì)資源的一種操作。
  • 2、客戶(hù)端和服務(wù)器之間,傳遞這種資源的某種表現(xiàn)層。
  • 3、客戶(hù)端通過(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.用于訪(fǎng)問(wèn)zhangsan的信息
http://192.168.1.102:8080/android/user/users/zhangsan
2.用于訪(fǎng)問(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í)行。這種的類(lèi)型的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.用于訪(fǎng)問(wèn)zhangsan的信息
http://192.168.1.102:8080/android/user/users/?name=zhangsan
2.用于訪(fǎng)問(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添加用戶(hù),通過(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ì),表示用戶(hù)的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ù)用戶(hù)的需求對(duì)結(jié)果進(jìn)行不同類(lèi)型的解析。
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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,564評(píng)論 19 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,045評(píng)論 25 709
  • API定義規(guī)范 本規(guī)范設(shè)計(jì)基于如下使用場(chǎng)景: 請(qǐng)求頻率不是非常高:如果產(chǎn)品的使用周期內(nèi)請(qǐng)求頻率非常高,建議使用雙通...
    有涯逐無(wú)涯閱讀 2,927評(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閱讀 56,204評(píng)論 24 557
  • 一:合作(美容院 婚慶 攝影 紋身 宗教 醫(yī)院/寵物店 銀行 金融 海外)等機(jī)構(gòu)合作 二:定位 名人明星官員 提供...
    光鋒容閱讀 560評(píng)論 0 0

友情鏈接更多精彩內(nèi)容