Mvp+RxJava+Retrofit现在越来越成熟了,网上的开源项目都在使用这样的框架,所以自己结合一些资料,总结一个简单浅显的例子入门。
1.MVP
Model View Presenter
View 是一个接口,回调结果的显示 onSuccess() onResult()等
Model 数据网络 初始化客户端,发起请求 execute()
Present 持有View 和 Model ,在自己方法中调用他们各自的请求方法和回调结果方法
Activity/Fragment : 持有Presnter 实现 View 接口 Presenter 发送请求,回调接口。
(Model 还是指的数据逻辑和实体模型,View指的是Activity,P就是Presenter)框架的工作方式。
2.Retrofit2
一个类型安全的用于Android和Java网络请求的客户端。retrofit2 仅仅是对okhttp的一个封装
正真的请求底层OkHttp 请求的。
1. 需要导入包:
- compile ‘com.squareup.retrofit2:retrofit:2.1.0’
- compile ‘com.squareup.retrofit2:converter-gson:2.1.0’
2. 测试的接口
https://api.github.com/users/xiaoduoduo
3. 返回json格式
{
"login": "xiaoduoduo",
"id": 7867197,
"avatar_url": "https://avatars0.githubusercontent.com/u/7867197?v=3",
"gravatar_id": "",
"url": "https://api.github.com/users/xiaoduoduo",
"html_url": "https://github.com/xiaoduoduo",
"followers_url": "https://api.github.com/users/xiaoduoduo/followers",
"following_url": "https://api.github.com/users/xiaoduoduo/following{/other_user}",
"gists_url": "https://api.github.com/users/xiaoduoduo/gists{/gist_id}",
"starred_url": "https://api.github.com/users/xiaoduoduo/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/xiaoduoduo/subscriptions",
"organizations_url": "https://api.github.com/users/xiaoduoduo/orgs",
"repos_url": "https://api.github.com/users/xiaoduoduo/repos",
"events_url": "https://api.github.com/users/xiaoduoduo/events{/privacy}",
"received_events_url": "https://api.github.com/users/xiaoduoduo/received_events",
"type": "User",
"site_admin": false,
"name": "kevin",
"company": "HuiFuCompany",
"blog": "",
"location": "ShangHai",
"email": null,
"hireable": null,
"bio": null,
"public_repos": 50,
"public_gists": 0,
"followers": 0,
"following": 0,
"created_at": "2014-06-12T05:54:10Z",
"updated_at": "2017-05-17T07:35:55Z"
}
4. 创建实体类
使用AS插件,GsonFormt 就可以
5. 定义请求接口 GitHubService
public interface GithubService {
@GET("users/{user}")
Call<Github> getFeed(@retrofit2.http.Path("user") String user);
}
内容的补充:
- @Query(GET请求):用于url后拼接参数
@GET("book/search")
Call<Book> getSearchBook(@Query("q") String name);//name由调用着传入
相当于
@GET("book/search?q=name")
Call<Book> getSearchBook();
- @QueryMap(GET请求):当然如果参数比较多,那么可以封装一个Map中
@GET("book/search")
Call<Book> getSearchBook(@QueryMap Map<String,String> params);
- @Path(GET请求):用于替换url中某个字段
比如我们的例子GitHubService
@GET("group/{id}/users")
Call<Book> groupList(@Path("id") int groupId);
group/1/users?sort=2
- @Body(POST请求):可以制定一个对象为请求体
@POST("users/new")
Call<User> createUser(@Body User user);
- @Field(POST请求):用于表单上传 需要加@FormUrlEncoded
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
- @Header/@Headers(POST请求):用于添加头部请求
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
//表示将头部Authorization属性设置为你传入的authorization;当然你还可以用@Headers表示,作用是一样的比如:
@Headers("Cache-Control: max-age=640000")
@GET("user")
Call<User> getUser()
//当然你可以多个设置:
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
@GET("user")
Call<User> getUser()
6. 定义请求类
//接口返回的数据不是我们需要的实体类,我们需要调用addConverterFactory方法进行转换
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Path.API_GITHUB)
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().create()))
.build();
GithubService service = retrofit.create(GithubService.class);
Call<Github> call = service.getFeed("xiaoduoduo");
call.enqueue(new Callback<Github>() {
@Override
public void onResponse(Call<Github> call, Response<Github> response) {
tv_query.setText(response.body().toString());
}
@Override
public void onFailure(Call<Github> call, Throwable t) {
}
});
3.RxJava 异步
1. 添加库
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
2. 请求的完整代码:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Path.API_GITHUB)
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().create()))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//支持RxJava
.build();
3. 修改RetrofitService的代码:返回的Observable
Observable<Book> observable = service.getSearchBook("金瓶梅", null, 0, 1);
4. 请求代码
/** 请求事件发生在io线程中*/
observable.subscribeOn(Schedulers.io())
/** 请求完成发生在ui线程*/
.observeOn(AndroidSchedulers.mainThread())
/** 请求完成发生在ui线程*/
.subscribe(new Observer<Deliver>() {
@Override
public void onCompleted() {//所有事件请求完成
}
@Override
public void onError(Throwable e) {//请求的时候发生错误
}
@Override
public void onNext(Deliver deliver) {//这里的deliver就是我们请求接口返回的实体类
tv_query.setText(deliver.toString());
}
});
在上面中我们可以看到,事件的消费在Android主线程,所以我们还要在build.gradle中添加如下依赖:
compile ‘io.reactivex:rxandroid:1.2.0’