Retrofit结合RxJava使用指南.docx
- 文档编号:8667077
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:13
- 大小:21.11KB
Retrofit结合RxJava使用指南.docx
《Retrofit结合RxJava使用指南.docx》由会员分享,可在线阅读,更多相关《Retrofit结合RxJava使用指南.docx(13页珍藏版)》请在冰豆网上搜索。
Retrofit结合RxJava使用指南
Retrofit结合RxJava使用指南
Retrofit是一个当前很流行的网络请求库,官网的介绍是:
"Type-safeHTTPclientforAndroidandJava".本文介绍Retrofit的使用.
先介绍单独使用Retrofit进行网络请求,后面主要介绍和RxJava结合的请求,有实例代码.
Retrofit单独使用
Setup
首先在manifest中加上网络权限:
name="android.permission.INTERNET"/> 然后在app/build.gradle中加上依赖: compile'com.squareup.retrofit2: retrofit: 2.1.0' compile'com.google.code.gson: gson: 2.8.0' compile'com.squareup.retrofit2: converter-gson: 2.1.0' 准备API和model类 本例子中使用GithubAPI做请求. 以Github的RootEndpoint为例: . 首先,我们在命令行发送: curl 或者在Postman发送这个请求,两种方法都可以得到结果. 这个请求返回的是一个json. 利用这个网站: jsonschema2pojo,可以用json生成一个java类,比如上面这个,我们给它起名字叫Endpoints.java. 之后例子中的API都是这种方式,先发送请求得到json,然后转成java的model类. 利用Retrofit发送请求并得到结果 首先写一个ServiceGenerator类,用于生成service: publicclassServiceGenerator{ publicstaticfinalStringAPI_BASE_URL=""; privatestaticOkHttpClient.BuilderhttpClient=newOkHttpClient.Builder(); privatestaticRetrofit.Builderbuilder= newRetrofit.Builder() .baseUrl(API_BASE_URL) .addConverterFactory(GsonConverterFactory.create()); publicstatic Retrofitretrofit=builder.client(httpClient.build()).build(); returnretrofit.create(serviceClass); } } 这里指定了我们的baseurl. createService()方法返回的是一个泛型. 然后我们创建GithubService,注意这是一个接口: importcom.ddmeng.helloretrofit.data.models.Endpoints; importretrofit2.Call; importretrofit2.http.GET; importretrofit2.http.Url; publicinterfaceGitHubService{ @GET Call } 这里@GET指定了是一个GET请求,因为我们请求的就是baseurl,所以是这样写的. Endpoints类是这个请求所返回的json转化的java类. 好了,准备工作做完了,现在就可以请求并得到结果: 请求githubapi的rooturl,得到所有的endpoints: GitHubServicegitHubService=ServiceGenerator.createService(GitHubService.class); Call endpointsCall.enqueue(newCallback @Override publicvoidonResponse(Call Endpointsendpoints=response.body(); StringrepositoryUrl=endpoints.getRepositoryUrl(); LogUtils.i(repositoryUrl); Toast.makeText(MainActivity.this,"repositoryurl: "+repositoryUrl,Toast.LENGTH_LONG).show(); } @Override publicvoidonFailure(Call } }); 说明: 首先利用前面的ServiceGenerator来创建Service,然后调用接口中定义的getAllEndpoints()方法,此处传入了空字符串,因为我请求的就是baseurl. 同步和异步 这里注意用Retrofit请求的返回值是Call execute()是同步方法,返回Response enqueue()是异步方法,在上面的例子中用的就是这个,在回调onResponse()中返回了Response Converter Converter的作用: 如果不指定Converter,默认情况下Retrofit只能返回ResponseBody类型,加了Converter之后就可以返回我们定义的Model类型了. 所以Converter替我们做了json->model的工作. 本例子中ConverterFactory指定的是GsonConverterFactory.这里我们选的是GsonConverter,所以依赖的是com.squareup.retrofit2: converter-gson. Retrofit支持多种converters: Gson: com.squareup.retrofit2: converter-gson Jackson: com.squareup.retrofit2: converter-jackson Moshi: com.squareup.retrofit2: converter-moshi Protobuf: com.squareup.retrofit2: converter-protobuf Wire: com.squareup.retrofit2: converter-wire SimpleXML: com.squareup.retrofit2: converter-simplexml Scalars(primitives,boxed,andString): com.squareup.retrofit2: converter-scalars Path和参数 从上面返回的endpoints可以看到,user_url是: 这是一个带path参数的url,我们发请求的时候在{user}处写一个github用户名,即可得到该用户的信息,比如: 那么用Retrofit如何处理呢? 只需要在GithubService中增加一个方法,这样写: publicinterfaceGitHubService{ @GET Call @GET("users/{user}") Call } 使用时的方法完全一样,不再赘述,同理,如果要在后面加参数,可以用@Query. 更多注解的例子见官方网站: Retrofit Retrofit+RxJava RxJava近年来很流行,主要优势是流式操作,可以处理并行发送请求,使用灵活,线程切换容易. 当你要处理的逻辑比较复杂时,就会发现使用RxJava的优势. 以我们的例子来说,当前我们利用一个请求可以得到一个用户的信息并显示出来. 如果我们想得到这个用户的所有repo的所有者或者其他信息,所有他follow的人的信息,以及他们的repo的信息呢? 这就需要发很多个请求,并且其中有些请求是并行发送的,如果按照前面的方法,不断地在callback里面嵌套,那就太难看了. SetupwithRxJava 添加RxJava依赖 首先,添加RxJava和RxAndroid的依赖: compile'io.reactivex: rxjava: 1.2.2' compile'io.reactivex: rxandroid: 1.2.1' 注: 虽然在我写这篇文章的时候(2016.11.4)RxJava2.0刚刚release,但是我们还是先用RxJava1来写这个demo. 然后添加retrofit的adapter-rxjava: compile'com.squareup.retrofit2: adapter-rxjava: 2.1.0' 所以现在我们的依赖总的看起来是这样: dependencies{ compilefileTree(dir: 'libs',include: ['*.jar']) androidTestCompile('com.android.support.test.espresso: espresso-core: 2.2.2',{ excludegroup: 'com.android.support',module: 'support-annotations' }) compile"com.android.support: appcompat-v7: ${supportLibVersion}" compile"com.android.support: design: ${supportLibVersion}" compile"com.jakewharton: butterknife: ${butterKnifeVersion}" apt"com.jakewharton: butterknife-compiler: ${butterKnifeVersion}" compile'com.squareup.retrofit2: retrofit: 2.1.0' compile'com.google.code.gson: gson: 2.8.0' compile'com.squareup.retrofit2: converter-gson: 2.1.0' compile'com.squareup.retrofit2: adapter-rxjava: 2.1.0' compile'io.reactivex: rxjava: 1.2.2' compile'io.reactivex: rxandroid: 1.2.1' testCompile'junit: junit: 4.12' } Retrofit结合RxJava Retrofit.Builder()中加入这一行: .addCallAdapterFactory(RxJavaCallAdapterFactory.create()); ServiceGenerator变成这样: publicclassServiceGenerator{ publicstaticfinalStringAPI_BASE_URL=""; privatestaticOkHttpClient.BuilderhttpClient=newOkHttpClient.Builder(); privatestaticRetrofit.Builderbuilder= newRetrofit.Builder() .baseUrl(API_BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()); publicstatic Retrofitretrofit=builder.client(httpClient.build()).build(); returnretrofit.create(serviceClass); } } 这样我们在GithubService中定义的接口方法,既可以像原来一样返回Call,也可以返回Observable. Retrofit+RxJava请求实例 以单个请求为例, 不用RxJava的时候: @GET("users/{user}/following") Call 请求的时候是这样的: 请求指定用户follow的所有人: GitHubServiceservice=ServiceGenerator.createService(GitHubService.class); Call userFollowing.enqueue(newCallback @Override publicvoidonResponse(Call List peopleListAdapter.setUsers(followingUsers); peopleListAdapter.notifyDataSetChanged(); } @Override publicvoidonFailure(Call } }); 现在改用RxJava了,返回的不是Call而是Observable: @GET("users/{user}/following") Observable 结合RxJava请求的时候变为这样: 还是请求用户follow的所有人: GitHubServiceservice=ServiceGenerator.createService(GitHubService.class); Stringusername=inputUserNameView.getText().toString(); service.getUserFollowingObservable(username) .subscribeO(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(newSubscriber @Override publicvoidonCompleted(){ } @Override publicvoidonError(Throwablee){ } @Override publicvoidonNext(List LogUtils.i("onNext: "+users.size()); peopleListAdapter.setUsers(users); peopleListAdapter.notifyDataSetChanged(); } }); 用RxJava实现后,请求返回的是一个Observable,用subscribe()添加一个订阅者,即它的观察者. 当请求返回后,回到主线程,更新UI. 这是单个请求的例子,所以RxJava的优势不是很明显,如果我们有多个请求,用RxJava进行变换组合显然就是更好的选择. 用RxJava进行线程切换 上个例子中.subscribeOn(Schedulers.io())指定Observable的工作,在我们的例子中Observable的工作即发送请求,在io线程做,指定了被观察者的处理线程; .observeOn(AndroidSchedulers.mainThread())指定最后onNext()回调在主线程,即指定了通知后续观察者的线程. 关于这两个操作符的更多说明请看官方文档: subscribeOn和observeOn. RxJava处理多个请求的例子 设计这样一个场景,我们现在取到了一个用户follow的所有人,但是取回的信息中并不包含每个人拥有的repo个数,只有一个url可用户查看所有repo. 接下来我们要取其中每一个人的详细信息,就要查询另一个API,重新查询这个人的完整信息. 查询用户follow的所有人,然后查询每一个人的详细信息: subscription=service.getUserFollowingObservable(username) .flatMap(newFunc1 @Override publicObservable returnObservable.from(users); } }) .flatMap(newFunc1 @Override publicObservable returnservice.getUserObservable(user.getLogin()); } }) .toList() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(newSubscriber @Override publicvoidonCompleted(){ } @Override publicvoidonError(Throwablee){ } @Override publicvoidonNext(List peopleListAdapter.setUsers(users); peopleListAdapter.notifyDataSetChanged(); } }); 可以看到我们加了两个flatMap()和一个toList()来做这个事情. 首先,第一步我们用getUserFollowingObservable()得到的是一个Observable 我们之后用.flatMap(),它的输入是List 之后第二个.flatMap()里,输入是前一个Observable的输出,即User,调用了getUserObservable(),返回的结果是Observable 只不过此时得到的用户信息是更详细的用户信息,包含了他的repo数据和follow数据.因为它们是通过单独查询每一个人得到的. 运行,虽然可以得到我们想要的结果,但是这个例子仍然是有问题的. 线程问题处理 上面多个请求的例子,发现虽然实现了我们的需求,但是结果回来得很慢. 我们加上一个.map操作符来加上log: (这里省略了一些前后的代码,只是在.flatMap()里加了一个.map()) ... subscription=service.getUserFollowingObservable(username) .flatMap(newFunc1 @Override publicObservable returnObservable.from(users); } }) .flatMap(newFunc1 @Override publicObservable returnservice.getUserObservable(user.getLogin()) .map(newFunc1 @Override publicUsercall(Useruser){ //this.mapisusedtooutputloginformationtocheckthethreads LogUtils.i("getUserObservable: "+user.getLogin()); returnuser; } }); } }) .toList()ScreateService(ClassserviceClass){ScreateService(ClassserviceClass){>getUserFollowing(@Path("user")Stringuser);
>userFollowing=service.getUserFollowing(inputUserNameView.getText().toString());
>(){
>call,Response
>response){
>call,Throwablet){
>getUserFollowingObservable(@Path("user")Stringuser);
>(){
,Observable
>(){
>;
,Observable
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Retrofit 结合 RxJava 使用指南
![提示](https://static.bdocx.com/images/bang_tan.gif)