Android-Rxjava&retrofit&daggerAndroid开发经验谈Android开发

Android - 网络请求之 Retrofit2 + RxJa

2017-12-28  本文已影响282人  Allens_Jiang
老婆保佑,代码无BUG

目录


一:引用

retrofit 官网

compile 'com.squareup.retrofit2:retrofit:2.3.0'

二:与其他开源请求库对比

image

三:Retrofit注解

四:使用

GET请求

(1) 定义接口


public interface ApiService {
    @GET
    Call<ResponseBody> getGetData(@Url String url);
    
    //Get请求,方法中指定@Path参数和@Query参数
    //@path参数用于替换url中{}的部分,
    //@Query将在url地址中追加类似"page=1"的字符串
    @GET("{mobile}/get?") 
    Call<ResponseBody> getPathData(@Path("mobile") String mobile, @Query("phone") String phone, @Query("key") String key);

    @GET("mobile/get?")
    Call<ResponseBody> getQueryMapData(@QueryMap Map<String, String> map);

}

(2) Activity

    public void btnYS(View view) {
        String baseUrl = "http://apis.juhe.cn/";
        String url = baseUrl + "mobile/get?phone=18856907654&key=5778e9d9cf089fc3b093b162036fc0e1";
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .build();
        ApiService apiService = retrofit.create(ApiService.class);
        
        //第一种
        Call<ResponseBody> call = apiService.getGetData(url);
        
        //第二种
        HashMap<String, String> map = new HashMap<>();
        map.put("phone", "18856907654");
        map.put("key", "5778e9d9cf089fc3b093b162036fc0e1");
        Call<ResponseBody> call = apiService.getQueryMapData(map);
        
        //第三种
        apiService.getPathData("mobile","18856907654","5778e9d9cf089fc3b093b162036fc0e1");
        
        
        
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                //主线程
                try {
                    Logger.e("response---->" + response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Logger.e("Throwable---->" + t.getMessage());
            }
        });
    }

POST请求

(1) 定义接口

public interface ApiService {
    @FormUrlEncoded
    @POST("mobile/get")  //注意  不是 /  结束
    Call<ResponseBody> postFile(@Field("phone") String phone,
                                @Field("key") String key);
                                
    @FormUrlEncoded
    @POST("mobile/get")  //注意  不是 /  结束
    Call<ResponseBody> postFile(@FieldMap Map<String,String> map);
}

(2) Activity

    public void btnPostFile(View view) {
        String baseUrl = "http://apis.juhe.cn/";
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .build();
        ApiService apiService = retrofit.create(ApiService.class);
        
        //第一种
        Call<ResponseBody> call = apiService.postFile("18856907654", "5778e9d9cf089fc3b093b162036fc0e1");
        
        //第二种
        HashMap<String, String> map = new HashMap<>();
        map.put("phone", "18856907654");
        map.put("key", "5778e9d9cf089fc3b093b162036fc0e1");
        Call<ResponseBody> call = apiService.postFile(map);
         //省略一下代码
    }

以上讲的都是废话,哈哈下面才是正确的打开放式


Retrofit2 + RxJava

引入 依赖

//Retrofit2
compile 'com.squareup.retrofit2:retrofit:2.3.0'
//RxJava
compile 'io.reactivex.rxjava2:rxjava:2.1.7'
//RxAndroid
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
//Retrofit 支持Rxjava 的支持库
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

先导入,然后慢慢说,这些都是干啥的

按套路出牌,肯定先写接口

public interface ApiService {
    @GET
    Observable<ResponseBody> getGetData(@Url String url);
}

看到这,就有兄弟说了,哥们你这里写错了,不应该是Observable应该是Call

u=1804519813,2654766997&fm=27&gp=0.jpg

都说了 之前说的都是屁话,这才是正确的打开方式,我们使用的是Observable,RxJava ,都是这么玩的 哈哈

so 继续

Activity 先来一个看看

package com.allens.retrofitdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String baseUrl = "http://apis.juhe.cn/";
        String url = baseUrl + "mobile/get?phone=18856907654&key=5778e9d9cf089fc3b093b162036fc0e1";


        // 设置网络请求的Url地址
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://fanyi.youdao.com/")
                // 支持RxJava平台
                //compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'   是他 就是他 
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

        retrofit.create(ApiService.class)
                .getGetData(url)//注意看,这里返回的对象时什么,和原生的返回不同,也是我们把上面接口改的原因
                //在子线程取数据
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                //在主线程显示ui 
                // compile 'io.reactivex.rxjava2:rxandroid:2.0.1'  这个库下才有AndroidSchedulers.mainThread
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<ResponseBody>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        
                    }

                    @Override
                    public void onNext(ResponseBody responseBody) {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });

    }
}

是不是感觉很简单。哈哈,对就是这么简单。Post 请求也这么玩,其他都不变,改一下接口,改成 Observable,然后使用RxJava 切换线程就哦了,

如果只是这种程度你就满足了,哈哈,大兄弟,你也太容易了,

其实我们还可以这么玩


五:优化

1. 设置数据解析器

(1)添加一条依赖

//gson 解析器
compile 'com.squareup.retrofit2:converter-gson:2.3.0'

修改接口

public interface ApiService {
    @GET
    Observable<Bean> getGetData(@Url String url);
}

找不同,哈哈 原来的是ResponseBody,现在是Bean,至于Bean 是什么,Bean 对象啊,大兄弟,这个不知道的话,表示。。。。

修改一下Activity中的代码

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://fanyi.youdao.com/")
                // 设置数据解析器
                .addConverterFactory(GsonConverterFactory.create()) 
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
retrofit.create(ApiService.class)
                .getGetData(url)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Bean>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Bean bean) {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });

可以看到,原来返回的是ResponseBody,现在返回的是已经解析成功的Bean 对象,

关于数据解析器(Converter)

数据解析器 Gradle依赖
Gson com.squareup.retrofit2:converter-gson:2.0.2
Jackson com.squareup.retrofit2:converter-jackson:2.0.2
Simple XML com.squareup.retrofit2:converter-simplexml:2.0.2
Protobuf com.squareup.retrofit2:converter-protobuf:2.0.2
Moshi com.squareup.retrofit2:converter-moshi:2.0.2
Wire com.squareup.retrofit2:converter-wire:2.0.2
Scalars com.squareup.retrofit2:converter-scalars:2.0.2

网络请求适配器(CallAdapter)

还记得compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' 么,他其实就是一个网络请求适配器
使用时如使用的是 Android 默认的 CallAdapter,则不需要添加网络请求适配器的依赖,否则则需要按照需求进行添加
Retrofit 提供的 CallAdapter
使用时需要在Gradle添加依赖:

网络请求适配器 Gradle依赖 备注
guava com.squareup.retrofit2:adapter-guava:2.0.2 没用过
Java8 com.squareup.retrofit2:adapter-java8:2.0.2 没用过
rxjava com.squareup.retrofit2:adapter-rxjava:2.0.2 retrofit现在只支持到rxjava1.XX
rxjava com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0. 大神写的这个库可以支持到rxjava2.X

到这里就是不是就感觉,人生圆满了呢,哈哈
还有后招呢,现在我想把服务端返回的数据全部打印出来,怎么做呢

u=1379330171,3486067710&fm=27&gp=0.jpg

2.加入拦截器

(1)导入库

compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'

(2)初始化HttpLoggingInterceptor

HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                //打印retrofit日志
                Log.i("RetrofitLog","retrofitBack = "+message);
            }
        });
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

(3)配置okhttp

client = new OkHttpClient.Builder()
                    .addInterceptor(loggingInterceptor)
                    .connectTimeout(mTimeOut, TimeUnit.SECONDS)
                    .readTimeout(mTimeOut, TimeUnit.SECONDS)
                    .writeTimeout(mTimeOut, TimeUnit.SECONDS)
                    .build();

然后嘛,

就可以在控制台看到请求的Log啦

12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> <-- 200 OK http://devapi.water.com/Oauth/authorize (185ms)
12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> Date: Thu, 28 Dec 2017 09:29:10 GMT
12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> Server: Apache/2.4.17 (Win64) OpenSSL/1.0.2d PHP/5.6.16
12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> X-Powered-By: PHP/5.6.16
12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> Content-Length: 104
12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> Keep-Alive: timeout=5, max=100
12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> Connection: Keep-Alive
12-28 04:29:07.337 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> Content-Type: application/json; charset=utf-8
12-28 04:29:07.338 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> 
12-28 04:29:07.338 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> {"is_success":true,"result":{"code":"9405f14110770bf8bd09d1397173e382eab923b19820b9330ce7d533cb3d4722"}}
12-28 04:29:07.338 3922-3944/com.allens.test E/XRetrofit: retrofitBack -> <-- END HTTP (104-byte body)

六: 最后在优化

哈哈,自己封装了一下,有兴趣的小伙伴可以点击查看,及使用

XRetrofit ,点击查看如何使用

上一篇下一篇

猜你喜欢

热点阅读