Rxjava+Retrofit基础学习

前段时间看了RxJava,发现跟他一起用的Retrofit,今天就把认识的他们俩个来总结梳理一下

一、什么是RxJava?(异步)

一个实现异步操作的库

给android开发者的RxJava详解

具体的看下这个链接,写的超级详细,超级好

二、什么是Retrofit?

网络请求的封装。

Android 网络(四) Retrofit学习笔记

Retrofit 是 Square 公司出品的默认基于 OkHttp 封装的一套 RESTful 网络请求框架,不了解 RESTful 概念的不妨去搜索学习下,RESTful 可以说是目前流行的一套 api 设计的风格,并不是标准。Retrofit 的封装可以说是很强大,里面涉及到一堆的设计模式,你可以通过注解直接配置请求,你可以使用不同的 http 客户端,虽然默认是用 http ,可以使用不同 Json Converter 来序列化数据,同时提供对 RxJava 的支持,使用Retrofit + OkHttp + RxJava + Dagger2可以说是目前比较潮的一套框架,但是需要有比较高的门槛。

Retrofit与picasso一样都是在okhttp基础之上做的封装,项目中可以直接用了。Retrofit因为也是Square出的,所以大家可能对它更崇拜些。Retrofit跟Volley是一个套路,但解耦的更彻底:比方说通过注解来配置请求参数,通过工厂来生成CallAdapter,Converter,你可以使用不同的请求适配器(CallAdapter), 比方说RxJava,Java8, Guava。你可以使用不同的反序列化工具(Converter),比方说json, protobuff, xml, moshi等等。炒鸡解耦,里面涉及到超多设计模式,个人觉得是很经典的学习案例。虽然支持Java8, Guava你可能也不需要用到。xml,protobuff等数据格式你也可能不需要解析。but,万一遇到鬼了呢。至于性能上,个人觉得这完全取决于请求client,也就是okhttp的性能,跟这些封装工具没太大关系。

Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。注意这里并没有说它是网络请求框架,主要原因在于网络请求的工作并不是 Retrofit 来完成的。Retrofit 2.0 开始内置 OkHttp,前者专注于接口的封装,后者专注于网络请求的高效,二者分工协作,宛如古人的『你耕地来我织布』,小日子别提多幸福了。

我们的应用程序通过 Retrofit 请求网络,实际上是使用 Retrofit 接口层封装请求参数、Header、Url 等信息,之后由 OkHttp 完成后续的请求操作,在服务端返回数据之后,OkHttp 将原始的结果交给 Retrofit,后者根据用户的需求对结果进行解析的过程。讲到这里,你就会发现所谓 Retrofit,其实就是 Retrofitting OkHttp 了。

三、引用例子1

1、添加依赖

compile'com.squareup.retrofit2:retrofit:2.1.0'                   //引入retrofit所用的依赖

compile'com.squareup.retrofit2:converter-gson:2.1.0'      //处理gson格式的数据,我们需要一个转换器,需要导入这个依赖

compile'com.squareup.retrofit2:adapter-rxjava:2.1.0'        //这两个是我们需要配合Rxjava使用所添加的依赖

compile'io.reactivex:rxandroid:1.0.1'

2、添加权限

毫不疑问,我们现在学习的是网络请求框架,自然需要添加网络请求的权限

<uses-permission android:name="android.permission.INTENET"

3、重要的来啦

我们这是一个很简单的demo,获取登录信息,接口为:https://api.github.com/users/{user}

定义一个接口包service

第一个接口

public interfaceLoginService {

@GET("/users/{user}")

Call<LoginModel>login(@Path("user") String user);

}

GET的意思是发送一个GET请求,请求的地址是:baseUrl+"/users/{user}"。{user}类似于占位符的作用,具体类型由 repo(@Path("user") String user) 指定,这里表示 {user} 将是一段字符串。

Call<LoginModel>是一个请求对象,<LoginModel>表示返回结果,是一个LoginModel类型的实例。

public class LoginModel{

privateString login;

publicStringgetLogin() {

returnlogin; 

}publicvoidsetLogin(String login) {

this.login = login; 

}}

接下来构造一个retrofit对象

Retrofit retrofit =newRetrofit.Builder()

.baseUrl("https://api.github.com")

.addConverterFactory(GsonConverterFactory.create())

.build();

注意这里添加的 baseUrl 和 GsonConverter,前者表示要访问的网站,后者是添加了一个JSON转换器。

创建API接口对象

LoginService service = retrofit.create(LoginService.class);

Call modelCall = service.login("lslolly");

注意这里的 .login("lslolly") 取代了前面的 {user}。到这里,我们要访问的地址就成了:

https://api.github.com/users/lslolly

最后就可以发请求了

modelCall.enqueue(newCallback() {

@Override

public voidonResponse(Call call,Response response) {

Toast.makeText(MainActivity.this,"请求正确的结果是:"+response.body().getLogin(),Toast.LENGTH_LONG).show();

tv_result.setText("请求结果为:"+response.body().getLogin());

}

@Override

public voidonFailure(Call call,Throwable t) {

Toast.makeText(MainActivity.this,"请求错误的结果是:"+t.getMessage(),Toast.LENGTH_LONG).show();

}

下面说下POST请求参数设置

POST 的请求与 GET 请求不同,POST 请求的参数是放在请求体内的。所以当我们要为 POST 请求配置一个参数时,需要用到 @Body 注解:

Call<LoginModel>post(@Body User user);//这里的 User 类型是需要我们去自定义的:

public class User{ 

publicString username; 

publicString password;

publicUser(String username,String password){

this.username = username;this.password = password;

}

//最后在获取请求对象时:

User user =newUser("lslolly","123456");

Call<LoginModel> model = service.post(user);

//完整代码实例如下

Retrofit retrofit =newRetrofit.Builder()

.baseUrl("https://api.github.com")

.addConverterFactory(GsonConverterFactory.create())

.build();

LoginService service = retrofit.create(LoginService.class);

Call<LoginModel>model =service.post(newUser("lolly","111111"));

model.enqueue(newCallback() {

@Override

public voidonResponse(Call call,Response response) {

Toast.makeText(MainActivity.this,"请求正确的结果是:"+response.body().getLogin(),Toast.LENGTH_LONG).show();

tv_result1.setText("请求结果为:"+response.body().getLogin());

}

@Override

public void onFailure(Call call,Throwable t) {

Toast.makeText(MainActivity.this,"请求错误的结果是:"+t.getMessage(),Toast.LENGTH_LONG).show();

}

});

四、例二

参考Retrofit使用教程(一)

使用的是百度的API Store提供的API,地址在此:手机号码归属地__API服务_API服务_API Store.

1.设置model

访问该API返回的数据格式如下:

{    "errNum":0,   

"retMsg":"success",   

"retData": {       

"phone":"15210011578", 

 "prefix":"1521001",  

"supplier":"移动",       

"province":"北京",       

"city":"北京",       

"suit":"152卡"}

}

根据返回结果我们创建数据对象PhoneResult,如下:

publicclassPhoneResult{/**

* errNum : 0

* retMsg : success

* retData : {"phone":"15210011578","prefix":"1521001","supplier":"移动","province":"北京","city":"北京","suit":"152卡"}

*/privateinterrNum;privateString retMsg;/**

* phone : 15210011578

* prefix : 1521001

* supplier : 移动

* province : 北京

* city : 北京

* suit : 152卡

*/

private RetDataEntity retData;

public void setErrNum(interrNum) {this.errNum = errNum;    }

public void setRetMsg(String retMsg) {this.retMsg = retMsg;    }publicvoidsetRetData(RetDataEntity retData) {this.retData = retData;    }publicintgetErrNum() {returnerrNum;    }publicStringgetRetMsg() {returnretMsg;    }publicRetDataEntitygetRetData() {returnretData;    }publicstaticclassRetDataEntity{privateString phone;privateString prefix;privateString supplier;privateString province;privateString city;privateString suit;publicvoidsetPhone(String phone) {this.phone = phone;        }publicvoidsetPrefix(String prefix) {this.prefix = prefix;        }publicvoidsetSupplier(String supplier) {this.supplier = supplier;        }publicvoidsetProvince(String province) {this.province = province;        }publicvoidsetCity(String city) {this.city = city;        }publicvoidsetSuit(String suit) {this.suit = suit;        }publicStringgetPhone() {returnphone;        }publicStringgetPrefix() {returnprefix;        }publicStringgetSupplier() {returnsupplier;        }publicStringgetProvince() {returnprovince;        }publicStringgetCity() {returncity;        }publicStringgetSuit() {returnsuit;        }    }}

2.构造接口

public interface PhoneService{   

@GET("/apistore/mobilenumber/mobilenumber")   

Call<PhoneModel>getResult(@Header("apikey") String apikey, @Query("phone") String phone);}

3.使用

privatestaticfinalString BASE_URL ="http://apis.baidu.com";privatestaticfinalString API_KEY ="8e13586b86e4b7f3758ba3bd6c9c9135";privatevoidquery(){//1.创建Retrofit对象Retrofit retrofit =newRetrofit.Builder()            .addConverterFactory(GsonConverterFactory.create())//解析方法.baseUrl(BASE_URL)//主机地址.build();//2.创建访问API的请求PhoneService service = retrofit.create(PhoneService.class);    Call call = service.getResult(API_KEY, phoneView.getText().toString());//3.发送请求call.enqueue(newCallback() {        @OverridepublicvoidonResponse(Call call, Response response) {//4.处理结果if(response.isSuccess()){                PhoneResult result = response.body();if(result !=null){                    PhoneResult.RetDataEntity entity = result.getRetData();                }            }        }        @OverridepublicvoidonFailure(Call call, Throwable t) {        }    });}

四、query,head

参考Retrofit使用教程(二)

1.query

//如12306的查询接口https://kyfw.12306.cn/otn/lcxxcx/query?//purpose_codes=ADULT&queryDate=2016-03-18&from_station=BJP&to_station=CDW,写法如下:@GET("/otn/lcxxcx/query")Callquery(@Query("purpose_codes")Stringcodes, @Query("queryDate")Stringdate,    @Query("from_station")Stringfrom, @Query("to_station")Stringto)

2.head

//比如要更新某个账户信息,其接口地址为/info,需要带的Header有设备信息device,//系统版本version,还要带请求参数要更新账户的id,代码如下:@POST("/info")Call updateInfo(@Header("device")Stringdevice, @Header("version")intversion,                        @Field("id")Stringid);

五、Retrofit中使用RxJava

参考Retrofit使用教程(三):Retrofit与RxJava初相逢

//使用RxJava我们则返回一个可被观测的PhoneResult:Observable,如下:

@GET("/apistore/mobilenumber/mobilenumber")ObservablegetPhoneResult(@Header("apikey") String apikey,                                      @Query("phone") String phone);//为了能返回此对象,我们需要在创建Retrofit对象时添加一个RxJava对象的Adapter来自动完成:Retrofit retrofit =newRetrofit.Builder()        .baseUrl(BASE_URL)        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())        .addConverterFactory(GsonConverterFactory.create())        .build();//获取手机的归属地phoneService.getPhoneResult(PhoneApi.API_KEY, number)        .subscribeOn(Schedulers.newThread())//子线程访问网络.observeOn(AndroidSchedulers.mainThread())//回调到主线程.subscribe(newObserver() {            @OverridepublicvoidonCompleted() {}            @OverridepublicvoidonError(Throwable e) {}            @OverridepublicvoidonNext(PhoneResult result) {if(result !=null&& result.getErrNum() ==0) {                    PhoneResult.RetDataEntity entity = result.getRetData();                    resultView.append("地址:"+ entity.getCity());                }            }        });}


好啦,简单易懂的叙述就到此为止啦,宝宝要去练习封装啦!完整demo如下:

demo地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,392评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • 前言RxJava和Retrofit也火了一段时间了,不过最近一直在学习ReactNative和Node相关的姿势,...
    AFinalStone阅读 536评论 0 0
  • 我从去年开始使用 RxJava ,到现在一年多了。今年加入了 Flipboard 后,看到 Flipboard 的...
    Jason_andy阅读 5,451评论 7 62
  • 读书:听书《混乱》《博罗奔尼撒战争》 修改:阅读讲解音乐调整, 点评:作文一篇 弹琴:20分钟 会议总结回馈:永林...
    躲进小楼看灯火阅读 136评论 0 0