Android | Retrofit簡(jiǎn)單封裝及注解的使用

此篇文章主要記錄下自己使用Retrofit后簡(jiǎn)易的封裝软吐,和相對(duì)全面的請(qǐng)求類型的注解使用方法,也是對(duì)知識(shí)點(diǎn)的一個(gè)總結(jié)和復(fù)習(xí)。

Retrofit是什么衩椒?

簡(jiǎn)單來(lái)說(shuō)Retrofit是一個(gè)網(wǎng)絡(luò)請(qǐng)求框架,基于OkHttp做了進(jìn)一步封裝哮兰,更好的適用于RESTful URL格式風(fēng)格毛萌,通過(guò)注解配置參數(shù),可以靈活的設(shè)置URL喝滞、請(qǐng)求頭阁将、請(qǐng)求體等。

優(yōu)點(diǎn)

  • 超級(jí)解耦
  • 處理速度快
  • 使用靈活方便
  • 可以使用注解控制請(qǐng)求的參數(shù)

封裝

public class RetrofitManager {
    private static RetrofitManager mRetrofitManager;
    private Retrofit mRetrofit;
    private static Context mContext;

    public RetrofitManager(Context context) {
        this.mContext = context;
        initRetrofit();
    }

    public static synchronized RetrofitManager getInstance(){
        if (mRetrofitManager == null){ mRetrofitManager = new RetrofitManager(mContext);}
        return mRetrofitManager;
    }

    private void initRetrofit(){
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        //添加攔截器
        builder.addInterceptor(new ResponseInterceptor ());
        builder.addInterceptor(new RequestInterceptor ());
        OkHttpClient client = builder
                //設(shè)置請(qǐng)求超時(shí)時(shí)間
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .build();

        mRetrofit = new Retrofit.Builder()
                .baseUrl(AlderApiService.BASE_URL)
                // addConverterFactory 對(duì)服務(wù)器數(shù)據(jù)進(jìn)行解析
                .addConverterFactory(GsonConverterFactory.create())//利用Gson解析返回的json
                .addConverterFactory(ScalarsConverterFactory.create())
                .client(client)
                .build();
    }

    public <T> T createReq(Class<T> reqServer){
        return mRetrofit.create(reqServer);
    }
}

一般使用時(shí)只用調(diào)用這個(gè)類就行了右遭,這里主要添加了請(qǐng)求的攔截器做盅、設(shè)置請(qǐng)求的超時(shí)時(shí)間疚脐、對(duì)添加請(qǐng)求的base url阅茶、添加對(duì)服務(wù)器返回?cái)?shù)據(jù)的解析。

攔截器

public class ResponseInterceptor implements Interceptor {
    private final String TAG = "ResponseInterceptor ";

    @Override
    public Response intercept(Chain chain) throws IOException {
        Response response = chain.proceed(chain.request());
        if(response!= null){
            if ( response.header("token") != null ){
                //獲取請(qǐng)求頭中的token 并保存在sp中
                final String token = response.header("token");
                SharedPreferencesUtils.getInstance().putString(SharedPreferencesUtils.TOKEN,token);
                Log.e(TAG,"保存在本地的token為:"+token);
            }
        }
        return response;
    }
}

獲取Response的請(qǐng)求頭內(nèi)容畏吓,項(xiàng)目里只用到了token滚婉,所以這里只獲取了token進(jìn)行保存图筹。

public class RequestInterceptor implements Interceptor {

    }
}    private final String TAG = "RequestInterceptor ";

    @Override
    public Response intercept(Chain chain) throws IOException {

        final Request.Builder builder = chain.request().newBuilder();

        String token = SharedPreferencesUtils.getInstance().getString(SharedPreferencesUtils.TOKEN,"");
        if (!token.isEmpty()&& null!=token&& !"".equals(token)){
            //添加請(qǐng)求頭,攜帶token
            builder.addHeader("token",token);
            Log.i(TAG,"攜帶的本地token為:"+token);
        }
        return chain.proceed(builder.build());

給Request請(qǐng)求頭中添加token。

Retrofit Service

我是主要在這里管理各個(gè)請(qǐng)求和base url满哪,貼個(gè)圖婿斥,大概格式就是這樣


image.png

封裝好后該如何使用劝篷?

簡(jiǎn)單粗暴上代碼

 public void registerSubmit(String name,String pwd,String email){
        mIRegisterView.showSubmitWaitDialog();
        RetrofitManager retrofitManager = new RetrofitManager(mContext);
        AlderApiService.RegisterService registerService = retrofitManager.createReq(AlderApiService.RegisterService.class);
        Call<Result> requestBodyCall = registerService.register(name,pwd,email);
        requestBodyCall.enqueue(new Callback<Result>() {
            @Override
            public void onResponse(Call<Result> call, Response<Result> response) {
                mIRegisterView.dismissSubmitWaitDialog();
                Result result = response.body();
                Log.i(TAG,"result : "+result.toString());
                if(response.body() != null){
                    if (result.isResult()){
                     //success
                    }else {
                    //fail
                    }
                }else {
                    mIRegisterView.OnRegisterFailed(ErrorCode.REQUEST_BODY_ERROR);
                }
            }

            @Override
            public void onFailure(Call<Result> call, Throwable t) {
                mIRegisterView.dismissSubmitWaitDialog();
                mIRegisterView.OnRegisterFailed(ErrorCode.NETWORK_ERROR);
            }
        });

    }

注解的使用

下面列舉的不是全部的注解,只是列舉了在不同請(qǐng)求中遇到過(guò)使用過(guò)的注解民宿。

POST請(qǐng)求

1. 普通的表單格式提交

@FormUrlEncoded  表單格式
@POST            post請(qǐng)求方式
@Field           表單提交參數(shù)

一般這三個(gè)注解會(huì)一起使用娇妓,例如:

   @FormUrlEncoded
   @POST("v1/user/login")
   Call<Result> login(@Field("userName") String userName);

這里@Field 中的userName是接口中定義的參數(shù)名,后面的userName是本地調(diào)用時(shí)傳的參數(shù)


2. 提交json格式

@Headers  添加請(qǐng)求頭
@Body     請(qǐng)求攜帶的參數(shù)(對(duì)象類型)

這里添加請(qǐng)求頭和我們前面在攔截器中添加都可以活鹰,因?yàn)檫@個(gè)請(qǐng)求方式是極少數(shù)哈恰,所以只是在這里單獨(dú)添加,內(nèi)容類型為json

@Headers({"Content-Type:application/json","Accept: application/json"})
@POST("v1/user/remove")
Call<Result> deleteUser(@Body RequestBody requestBody);

@Body 就是傳入的參數(shù)為RequestBody類型

這個(gè)方法調(diào)用時(shí)傳入的參數(shù)為這樣

RequestBody body=RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"),json.toString());

一般這種提交是用在批量刪除的時(shí)候志群,將id集合以json的形式提交着绷。

3. 路徑中攜帶參數(shù)

@Path   將參數(shù)放在路徑中
 @FormUrlEncoded
 @POST("v1/panel/{imei}")
 Call<Result<Integer>> armControl(@Path("imei") String imei,@Field("armingLevel") int armingLeve);

@Path 有一些提交的參數(shù)是明文提交,也就是直接在url路徑中顯示的锌云,這時(shí)用到的注解就是TA

GET請(qǐng)求

1. 普通get

@GET   get請(qǐng)求方式
 @GET("v1/user/info")
 Call<Result<AccountInformation>> getAccount();

@GET 這個(gè)注解就不用做過(guò)多解釋了荠医,和post為兩種請(qǐng)求方式

2. 帶參get請(qǐng)求①

@GET("v1/camera/{deviceID}")
Call<GetCamera> getCameraInfo(@Path("deviceID") Integer deviceID);

這里有用到@Path,用法其實(shí)是一樣的桑涎,在url中攜帶參數(shù)彬向。

3. 帶參get請(qǐng)求②

@Query         請(qǐng)求攜帶參數(shù)
@QueryMap      請(qǐng)求攜帶參數(shù)集合
 @GET("v1/notification")
 Call<Result<Map<String,List<Notification>>>> getNotification(@Query("cameraId") String cameraId);

@Query 在一定意義上和@Path是差不多的,最終的參數(shù)都是在請(qǐng)求的url中攻冷,@Query 是不需要我們自己在url中寫參數(shù)的key娃胆,url最終的效果是v1/notification?cameraId=xxx,用上面的栗子來(lái)看的話 @Path url最終的效果是v1/camera/xx

DELETE請(qǐng)求

 @DELETE   刪除
 @DELETE("rest/{deviceID}")
 Call<String> deleteCamera(@Path("deviceID") String deviceID);

一般這樣的操作等曼,在后臺(tái)提供的接口時(shí)也需要使用RESTful風(fēng)格中的@DELETE來(lái)匹配

目前在項(xiàng)目中常用的一些注解和封裝方法就醬紫啦里烦,寫的比較基礎(chǔ),也沒(méi)有實(shí)在性的技術(shù)語(yǔ)言去講解禁谦,但把如何使用的例子都貼的很清楚胁黑,我覺(jué)得有些東西能說(shuō)出來(lái)并不一定會(huì)用,但是當(dāng)你會(huì)用了就一定能說(shuō)州泊,不應(yīng)該把對(duì)技術(shù)的學(xué)習(xí)停留在理論上 -.而且對(duì)于菜鳥的我來(lái)說(shuō)别厘,在網(wǎng)上查到的一些結(jié)束貼,大部分都是文字說(shuō)明文字說(shuō)明文字說(shuō)明....看的到最后頭大了都不知道該怎么去用拥诡,把怎么用講清楚最實(shí)在触趴。
還有很多注解沒(méi)有寫到,等以后用了再繼續(xù)補(bǔ)充~~
希望在技術(shù)的路上越走越好~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末渴肉,一起剝皮案震驚了整個(gè)濱河市冗懦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌仇祭,老刑警劉巖披蕉,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡没讲,警方通過(guò)查閱死者的電腦和手機(jī)眯娱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)爬凑,“玉大人徙缴,你說(shuō)我怎么就攤上這事∴倚牛” “怎么了于样?”我有些...
    開(kāi)封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)潘靖。 經(jīng)常有香客問(wèn)我穿剖,道長(zhǎng),這世上最難降的妖魔是什么卦溢? 我笑而不...
    開(kāi)封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任糊余,我火速辦了婚禮,結(jié)果婚禮上单寂,老公的妹妹穿的比我還像新娘啄刹。我一直安慰自己,他們只是感情好凄贩,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著袱讹,像睡著了一般疲扎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上捷雕,一...
    開(kāi)封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天椒丧,我揣著相機(jī)與錄音,去河邊找鬼救巷。 笑死壶熏,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的浦译。 我是一名探鬼主播棒假,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼精盅!你這毒婦竟也來(lái)了帽哑?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤叹俏,失蹤者是張志新(化名)和其女友劉穎妻枕,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屡谐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年述么,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愕掏。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡度秘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出亭珍,到底是詐尸還是另有隱情敷钾,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布肄梨,位于F島的核電站阻荒,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏众羡。R本人自食惡果不足惜侨赡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望粱侣。 院中可真熱鬧羊壹,春花似錦、人聲如沸齐婴。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)柠偶。三九已至情妖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間诱担,已是汗流浹背毡证。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔫仙,地道東北人料睛。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像摇邦,于是被迫代替她去往敵國(guó)和親恤煞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

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