关于使用retrofit框架的网络请求方法使用例子,同时+MVP +rxjava + rxandroid使用
今天去看了下关于一个新的网络请求框架--retrofit,之前就已经了解和使用volley,okhttp和imageloader等网络请求框架,当然还有原生的http请求。这些各自有各自的优缺点。我这里就不做评论了,只做使用简介。
Retrofit是一个不错的网络请求库,用官方自己的介绍就是:
A type-safe REST client for Android and Java
这个网络请求框架,毕竟是Google的亲生儿子,支持什么的都很不错。
关于详细的retrofit请点击以下链接:
https://futurestud.io/blog/retrofit-getting-started-and-android-client#
点击打开链接一开始入门的时候,找了不少资料,都是直奔用法的,一些语法之前没怎么看过,所以就显得不怎么看得懂。像是如何拼接url等等的语法,都不是直接 + 的。第一次看起来很生涩难懂。例如:
@GET("repos/{user}/{psw}/contributors")
Call<List<GithubUser>> getDataByLs(@Path("user") String user, @Path("psw") String psw);
@GET -get方式请求数据???
(“repos/{user}/{psw}/contributors”) -???
@Path("user") String user -???
是不是很蒙?好多看不懂啊。。。。。
但是我这里给你一个解释的版本,让你好好理解:
/**
* @GET 使用get方法请求数据
* 括号里面的是网站的后缀url地址
* 而在baseurl则是在retrofit里面设定了
* {user} = 要传入的参数 由函数参数传参——》@Path("user") String user
* {psw} = 要传入的参数 由函数参数传参——》@Path("psw") String psw
* 最后拼成的url地址为:https://api.github.com/repos/user/psw/contributors
*
* @param user user
* @param psw psw
* @return Call<List<GithubUser>>
*/
@GET("repos/{user}/{psw}/contributors")
Call<List<GithubUser>> getDataByLs(@Path("user") String user, @Path("psw") String psw);
更多详细的解释,请站在巨人的肩膀上吧:
实例开始位置--------------------------
首先在项目的build.gradle文件的dependencies加入gradle依赖包:
compile 'io.reactivex:rxandroid:1.0.1'
compile 'io.reactivex:rxjava:1.0.14'
//retrofit
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
//RxJava 适配器
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
我在项目里面使用的MVP + Rxjava + Rxandroid 的结构来做,以下是我的部分重要代码展示,解释直接看代码注释就好了。
首先你要知道请求回来的数据是什么类型的,比如gson类型的,retrofit默认的认为服务器返回的是gson格式的数据。所以我们首先要有一个bean。如下:
/**
* bean类
*
* Created by kuyu.yaojt on 16/5/19.
*/
public class GithubUser {
private String login;
private int id;
private int contributions;
@Override
public String toString() {
return "GithubUser{" +
"login='" + login + '\'' +
", id=" + id +
", contributions=" + contributions +
'}';
}
public GithubUser(String login, int id, int contributions) {
this.login = login;
this.id = id;
this.contributions = contributions;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getContributions() {
return contributions;
}
public void setContributions(int contributions) {
this.contributions = contributions;
}
}
很简单的一个实体类,重写了tostring方法,用来打印实体类的全部属性,这个很实用。
然后定义一个方法的接口
/**
* 请求github的接口
*
* Created by kuyu.yaojt on 16/5/19.
*/
public interface GitHubNetworkInterface {
/**
* @GET 使用get方法请求数据
* 括号里面的是网站的后缀url地址
* 而在baseurl则是在retrofit里面设定了
* {user} = 要传入的参数 由函数参数传参——》@Path("user") String user
* {psw} = 要传入的参数 由函数参数传参——》@Path("psw") String psw
* 最后拼成的url地址为:https://api.github.com/repos/user/psw/contributors
*
* @param user user
* @param psw psw
* @return Call<List<GithubUser>>
*/
@GET("repos/{user}/{psw}/contributors")
Call<List<GithubUser>> getDataByLs(@Path("user") String user, @Path("psw") String psw);
}
这里定义了一个接口。
为什么用接口来定义?我这里还有点模糊,待会看源码,求解释。
然后就是比较熟悉的MVP模式啦,依次创建M, V, P 的接口或者类,如果不太熟悉MVP的可以去百度一下MVP模式。
当然还有rxjava和rxandroid的观察者模式,我觉得这个还是挺好的,至少我们可以把代码解耦很多,结构也很清晰,虽然类多了n倍多。--这方面不是很熟悉的,请去百度,这里不做过多解释。
在我的登陆页面的m里面
/**
* 登陆页面的视图控制层
*
* Created by kuyu.yaojt on 16/5/14.
*/
public interface LoginView extends BaseCustomView{
void loginSuccess(JSONObject jsonObject);
void getDataSueecss(List<GithubUser> githubUserList);
}
定义了一个取数据返回成功的接口方法getDataSueecss(),然后你要做的就是在activity里面实现这个接口,并做更新ui的操作。
我这里LoginView.java的实现是这样的:
//接口实现
@Override
public void getDataSueecss(List<GithubUser> githubUserList) {
for(GithubUser githubUser : githubUserList){
System.out.println("-=-=-=-=>>toString() = " + githubUser.toString());
}
ToastUtils.makeText(this, "--->get Data From github Sueecss");
}
仅仅是做一个打印和弹窗而已。
然后是m类LoginModel.java:
/**
* 实际登陆操作类
* <p/>
* Created by tanksu on 16/5/4.
*/
public class LoginModel {
private int mCount;
private boolean mBoolean = true;
public LoginModel() {
}
/**
* 从Github上面获取数据
*
* @param name
* @param psw
* @return
*/
public Observable<List<GithubUser>> getDataFromGithub(String name, String psw) {
Observable mOservable = Observable.create(new Observable.OnSubscribe<List<GithubUser>>() {
@Override
public void call(Subscriber<? super List<GithubUser>> subscriber) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())//添加 json 转换器
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//添加 RxJava 适配器
.build();
//这里用到一个创建一个接口,来调用方法,请求网络
//Create an implementation of the API endpoints defined by the {@code service} interface.
GitHubNetworkInterface gitHub = retrofit.create(GitHubNetworkInterface.class);
Call<List<GithubUser>> call = gitHub.getDataByLs("square", "retrofit");
List<GithubUser> list = null;
try {
//execute() - 同步操作
//enqueue(Callback<T> callback) - 异步操作-用不到了,因为在观察者模式里面已经设置了在非ui线程中执行操作
//最后返回一个反序列化的结果
list = call.execute().body();
} catch (IOException e) {
e.printStackTrace();
}
subscriber.onNext(list);
subscriber.onCompleted();
}
});
return mOservable;
}
}
baseUrl(“https://api.github.com/“)--指的是服务器的地址,一般来说都是不变的
retrofit就在这里用到了,详细请看代码。
还有一点很重要,就是关于网络请求的异步问题,我们在观察者模式中,就开启了异步请求方式,所以我们这里不用再开一条线程来做网络请求操作了。
我的p类LoginPresenter.java:
public class LoginPresenter {private LoginView mLoginView;
private LoginModel mLoginModel;
private Context mContext;
/**
* 构造函数
*
* @param context
* @param baseCustomView
*/
public LoginPresenter(Context context, LoginView baseCustomView) {
this.mContext = (Context) baseCustomView;
this.mLoginView = baseCustomView;
mLoginModel = new LoginModel();
}
/**
* 在github上面获取数据
*
* @param name
* @param psw
*/
public void getDataFromGithub(String name, String psw) {
// 设置个2000ms的延迟,模拟网络访问、数据库操作等等延时操作
SystemClock.sleep(2000);
mLoginView.showProgressDialog();//在activity实现的通用用户友好体验的提示
mLoginModel.getDataFromGithub(name, psw)
.subscribeOn(Schedulers.io())//在非UI线程进行耗时操作
.observeOn(AndroidSchedulers.mainThread())//在UI线程进行观察监听
.subscribe(new Subscriber<List<GithubUser>>() {//开始订阅观察监听
@Override
public void onCompleted() {
mLoginView.hideProgressDialog();
}
@Override
public void onError(Throwable e) {
mLoginView.showError("--->>" + e.getMessage());
Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(List<GithubUser> githubUsers) {
mLoginView.hideProgressDialog();
mLoginView.getDataSueecss(githubUsers);
}
});
}
}
LoginPresenter是作为分发者的角色,m和v的唯一沟通协调人,因为我们在p里面所做的一切都是逻辑和消息分发处理,但是不做耗时的操作。耗时的操作是在m里面实现的。
这里采用了观察者模式, mLoginModel.getDataFromGithub(name, psw)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe()
--这里的方法就是,解释都在代码里面。
实例结束位置--------------------------
以上就是我个人对retrofit使用的个人见解,顺带说了下mvp, rxjava,rxandroid的小小使用,希望对各位有个引导学习进步作用。谢谢。
如有异议疑问,请与我联系。