小白装逼:Android retrofit2+rxjava

来源:互联网 发布:马岛海战 知乎 编辑:程序博客网 时间:2024/05/24 15:39
本人小白,最近接触了安卓的网络框架,特来此装逼,有误导之处,请及时指出,谢谢!首先说下retrofit这个东西,之前不知道有这东西,所以网络请求都是直接用socket来写,后来才知道有okhttp3,用了下发现有点复杂,就找到了retrofit2,个人感觉这个网络框架还是挺好用的而且用起来方便简洁,当然他的底层也是基于okhttp,最底层也是使用socket这东西。

retrofit的导入设置

首先是导入以来包,主要是导入retrofit2(这里面自己会导入okhttp3)、rxjava、gson(我这里的服务器使用json交互的,讲道理一般也是用这个的吧~~),大概是下面这些,应该没复制少
    compile 'com.squareup.retrofit2:retrofit:2.0.1'    compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'    compile 'io.reactivex:rxandroid:1.1.0'    compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'    compile 'com.squareup.retrofit2:adapter-rxjava:2.0.1'    compile 'com.google.code.gson:gson:2.6.2'
然后先写服务器交互的,api.java,apiService.java
public class Api {    public final static String API_BASE_URL="xxx";//这里是服务器连接的接口的固定部分    public static Api instance;//单例    private ApiService service;//声明apiservier,下面要通过这个调用与服务器交互的方法    //添加请求头拦截器,这个头部也可以在apiservice这个接口中添加    Interceptor mInterceptor =new Interceptor() {        @Override        public Response intercept(Chain chain) throws IOException {            try{                Request original = chain.request();                Request.Builder requestBuilder = original.newBuilder()//添加头部信息                        .addHeader("key", "value");//这里添加头部,这里可以用addHeader来添加多个头部,如果使用header方法就只能添加一个头部                Request request = requestBuilder.build();//用设置好的requestBuilder建立一个新的request                return chain.proceed(request);            }catch (SocketTimeoutException e){                return null;            }        }    };    public Api() {        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();//打印出请求的信息的拦截器        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);//设置打印请求的记录级别  NONE:不记录; BASIC:请求/响应行; HEADER:请求/响应行+请求头; BODY:请求/响应行+请求头+请求体(所有信息)        OkHttpClient okHttpClient = new OkHttpClient.Builder()//建立OkHttpClient,OkHttp3的连接及设置                .connectTimeout(10, TimeUnit.SECONDS)//请求连接超时10秒,这里有个writeTimeout没设置,方法跟其他超时的设置一样                .connectTimeout(20 * 1000, TimeUnit.MILLISECONDS)//请求连接超时20秒                .readTimeout(20 * 1000, TimeUnit.MILLISECONDS)//数据传输超时20秒                .addInterceptor(mInterceptor)//添加请求头的拦截器                .addInterceptor(interceptor)//打印请求信息拦截器                .retryOnConnectionFailure(true)//连接失败后重试(断网重连)                .build();            Retrofit retrofit = new Retrofit.Builder()//建立Retrofit                .baseUrl(API_BASE_URL)//连接服务器的基础接口                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//添加Rx适配器                .addConverterFactory(GsonConverterFactory.create()) // 添加Gson转换器                .client(okHttpClient)//设置OkHttp                .build();        service = retrofit.create(ApiService.class);//为retrofit创建请求服务器的接口.ApiService为一个接口,内部定义了请求服务器的方法    }    public static Api getInstance() {//获取单例        if (instance == null)            instance = new Api();        return instance;    }    //定义一个调用APIService中方法的方法,提供给需要使用这个请求的地方调用(get请求)    public Observable<VerificationCode> getCode(String header, String moblie) {        return service.getCode(moblie,"login");    }}
public interface ApiService {//    @Headers("key:value")//可以在此处添加请求头部,由于项目的头部需要转码,所以在api中设置了    //get请求    @GET("xxx")//申请类型注释,这里的xxx为此方法的服务器接口的变化部分,实际的接口为(固定+变化)    Observable<Data> getCode(@Query("mobile") String mobile, @Query("type") String login);//@query为参数注释,键值为mobile的mobile,键值为type的login    //post请求    @Multipart//方法注释    @POST("token/index/login")    Observable<Data2> login(@PartMap Map<String, RequestBody> bodyMap);    //返回值为observale被观察者,用于给rxjava异步处理,Data2为一个自定义的类,用于存放返回的数据}

retrofit常用注释说明:
1.申请类型注释: @GET请求、@POST请求,还有@DELETE请求等;;
2.方法注释:(可以没有),
@Multipart:标明请求方法的一个参数为一个部分,且参数需要有@Part注释;;
@Headers标明为申请的头部(多个),Header为一个;;
@FormUrlEncoded:标明请求参数将使用表单网址编码,参数需要使用@Field;;
3.参数注释:
@Body:参数不做处理直接发出,用于post和put请求;;
@Query(“xxx”):标明此参数的键值为xxx,当参数为数组或List时,会对每一个非空的item加上键值xxx,多用于get请求;;
@QueryMap:参数为一个map的query,其键值为map中的键值,多用于get请求;;
@Part:对应Multipart注释,使用该注解定义的参数类型有以下3种方式可选:
1, 如果类型是okhttp3.MultipartBody.Part,内容将被直接使用,即 @Part MultipartBody.Part xxx
2, 如果类型是RequestBody,那么该值将直接与其内容类型一起使用。 在注释中提供part名称(例如,@Part(“xxx”)RequestBody xxx)。
3, 其他对象类型将通过使用转换器转换为适当的格式。 在注释中提供part名称(例如,@Part(value = “image”, encoding = “8-bit”)Image photo)//value为类型,encoding为编码格式
@PartMap:对应Multipart注释,例:@PartMap Map< String, RequestBody> params,其中String为键值,RequestBody为内容正文(这里在使用时,需要转换表单类型,下面做说明)
注:RequestBody的java中表单类型转换代码:

Map<String, RequestBody> bodyMap = new HashMap<>();bodyMap.put("id", RequestBody.create(MediaType.parse("xxx"), mobile));//xxx为表单类型

常用的表单类型有(具体的可以查下Http MIME类型):
1.application/x-www-form-urlencoded(默认)
2.image/jpeg(jpeg格式的图片)
3.multipart/form-data(post的表单格式)
4.text/plain(txt的文本格式)

rxjava的配置

这里需要准备3个类,一个是回调时要执行的接口RxApiCallback,一个是回调执行的方法RxSubscriberCallBack(继承于Subscriber),还有管理订阅者的RxManager;
这里的RxApiCallback,RxManager不是必要存在的, 只是为了更好的处理和管理订阅才有的

public interface RxApiCallback<T> {    void onSuccess(T model);    void onFailure(int code, String msg);}

rxjava会回调一个继承Subscriber的类,并根据返回情况调用类中的3个方法

public class RxSubscriberCallBack<T> extends Subscriber<T> {    private RxApiCallback<T> rxApiCallback;    public RxSubscriberCallBack(RxApiCallback<T> mapiCallbackRx){        this.rxApiCallback = mapiCallbackRx;    }    @Override    public void onCompleted(){//事件队列中没有后续事件    }    @Override    public void onError(Throwable e) {//获取服务器信息失败        e.printStackTrace();        //网络        if (!NetWorkUtils.isNetConnected(App.getAppContext())) {//是否无网络            rxApiCallback.onFailure(0, RescourseUtils.getString(R.string.no_net));        }        //服务器        else{            rxApiCallback.onFailure(1, "获取数据失败");        }    }    @Override    public void onNext(T t) {//成功时回调            rxApiCallback.onSuccess(t);    }}
public class RxManager {    private CompositeSubscription mCompositeSubscription = new CompositeSubscription();// 管理订阅者者    //添加订阅者    public void add(Observable observable, Subscriber subscriber) {        mCompositeSubscription.add(                observable                        .subscribeOn(Schedulers.io())//设置调用方法前在io线程中执行                        .unsubscribeOn(Schedulers.io())//设置取消订阅在io线程中执行                        .observeOn(AndroidSchedulers.mainThread())//设置调用方法后在主线程中执行                        .subscribe(subscriber));//设置订阅者    }    取消所有订阅者    public void clear() {        mCompositeSubscription.unsubscribe();// 取消订阅    }}

数据存储类

上面用于数据存储的Data、Data2,其实只是一个普通的类,但是retrofit会根据服务器发回来的键值对应到Data中的属性名来赋值.

class Data{    private String name;    private String phone;    private String sex;    (省略:get...set...toString)}

在 此处的Data:
1.如果服务器回传的数据有name,sex键值的,会对应的给name,sex赋值,phone没有的则不会赋值;;
2.如果服务器回传的数据有like键值但Data中不存在,则不对like进行存储(即忽略这个值);;

使用retrofit+rxjava

前面的都设置好了, 到这里就要开始使用了

public RxManager mRxManager;public onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(main);    mRxManager=new RxManager();//创建rx管理者    //post    Map<String, RequestBody> bodyMap = new HashMap<>();    bodyMap.put("mobile", RequestBody.create(                MediaType.parse("multipart/form-data"), "123"));//将"123"转为表单写入bodyMap中    bodyMap.put("yzcode", RequestBody.create(                MediaType.parse("multipart/form-data"), "456"));    login( bodyMap);//发送请求    //get    getCode("123","456");//发送123,456的get请求}protected void onDestroy() {    super.onDestroy();    mRxManager.clear();//取消订阅}//post请求的loginprotected void login(Map<String, RequestBody> bodyMap) {        mRxManager.add(Api.getInstance().login(bodyMap),new RxSubscriberCallBack<Data2>(new RxApiCallback<Data2>() {//创建并加入订阅者            @Override            public void onSuccess(Data2 model) {//成功回调                Log.i("---login---","success:"+model.toString());            }            @Override            public void onFailure(int code, String msg) {//失败回调                Log.i("---login---","failure:"+msg);            }        }));    }//get请求的getCodeprotected void getCode(String mobile, String type) {        mRxManager.add(Api.getInstance().getCode(mobile,type),new RxSubscriberCallBack<Data>(new RxApiCallback<Data>() {            @Override            public void onSuccess(Data model) {                Log.i("---getCode---","success:"+model.toString());            }            @Override            public void onFailure(int code, String msg) {                Log.i("---getCode---","failure:"+msg);            }        }));    }

结尾吐槽

以上是本人项目中接触到的retrofit+rxjava,个人感觉十分的方便,十分的强大,而且此处的rxjava可以代替eventBus,这个我们下次在装逼.

以上内容,纯属个人理解,如有错误,请指出纠正,若有雷同,你肯定在做梦~~~~

原创粉丝点击