说起MVP+Retrofit2+RxJava还是自己来公司之后才了解到的,在此之前学习Java了解使用了MVC,甚知使用之后对于项目的维护和管理有这很大帮助,所以一直想很好的彻底的了解一下在Android中该如何使用,所以自己在网上学习做出了一个简单的栗子,希望对初学的人有所帮助!
前言...简单了解一下MVP,Retrofit2,RxJava各自的在项目中的作用
1.MVP,类似于MVC一种基于Android应用的模式,但稍有一些不同,就记住,Moudel与View不能直接联系就行,而MVC是可以的。
2.Retrofit2,一种网络请求框架,其实我现在也没有明白它的好处,嘿嘿,请见谅!
3.RxJava, 用于异步请求数据。
正文:此demo只是简单的登录、注册,带参传入,访问服务器,以验证正误
先看一下项目结构,该如何放置各个主要类,仅供参考
1.jar包添加
//网络请求框架
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
//异步请求
compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.5'
//自动注解
compile 'com.jakewharton:butterknife:7.0.1'
2.先说MVP的设计步骤,布局如下,我就不放XML文件了
这里有一个progressBar是隐藏的,登录注册请求期间显示,成功后隐藏。
1)设置Moudel中的实体类,以便数据的交互,实体类也很简单;
public class LoginResult {
public long time;
public long openid;
public UserBindInfo userBindInfo;
public int errno;
public String errmsg;
public String token;
public String UserLastLoginTime;
public class UserBindInfo {
public String user_is_set_question;
public String user_is_bind_email;
public String user_is_bind_phone;
}
}
2)设置View,就是在Activity中需要哪些返回数据做界面UI更新。
此demo中就是需要访问服务器之后,拿到返回数据来提示用户登录或者注册是否成功;
public interface ILoginView {
void onLoginResult(LoginResult result);
void onRegisterResult(RegisterResult result);
void onSetProgressBarVisibility(int visibility);
}
3)设置Presenter,编写一些在Activity中需要用到的逻辑代码,以减少Activity中的代码臃肿。
此demo中就是处理当点击登录或者注册后向服务器发送请求,和获取返回数据供Activity使用;
接口类:
public interface ILoginPresenter {
void login(String name, String pass);
void register(String name, String pass);
}
实现类:
public class LoginPresenterImpl implements ILoginPresenter {
private ILoginView loginView;
private Context context;
public LoginPresenterImpl(Context context, ILoginView loginView) {
this.loginView = loginView;
this.context = context;
}
@Override
public void login(String user, String pswd) {
loginView.onSetProgressBarVisibility(View.VISIBLE);
//这里就是请求服务器的操作,也可以其他框架处理
RetrofitManager.getInstance().login(user, pswd, new BaseSubscribe<LoginResult>(context) {
@Override
protected void _onNext(LoginResult result) {
loginView.onLoginResult(result);
loginView.onSetProgressBarVisibility(View.GONE);
}
@Override
protected void _onError(Throwable e) {
loginView.onSetProgressBarVisibility(View.GONE);
}
});
}
@Override
public void register(String user, String pswd) {
loginView.onSetProgressBarVisibility(View.VISIBLE);
RetrofitManager.getInstance().register(user, pswd, new BaseCallback<RegisterResult>(context) {
@Override
protected void _onResponse(Response<RegisterResult> response) {
loginView.onRegisterResult(response.body());
loginView.onSetProgressBarVisibility(View.GONE);
}
@Override
protected void _onFailure(Throwable e) {
loginView.onSetProgressBarVisibility(View.GONE);
}
});
}
}
4)MainActivity中的使用
public class MainActivity extends AppCompatActivity implements ILoginView {
@Bind(R.id.user)
EditText username;
@Bind(R.id.pass)
EditText password;
@Bind(R.id.login)
Button login;
@Bind(R.id.register)
Button register;
@Bind(R.id.progress_login)
RelativeLayout relativeLayout;
private ILoginPresenter loginPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
ButterKnife.bind(this);
loginPresenter = new LoginPresenterImpl(this, this);
}
@OnClick({R.id.login, R.id.register})
public void onClick(Button button) {
switch (button.getId()) {
case R.id.login:
loginPresenter.login(getUsername(), getPassword());
break;
case R.id.register:
loginPresenter.register(getUsername(), getPassword());
break;
}
}
private String getUsername() {
return username.getText().toString();
}
private String getPassword() {
return password.getText().toString();
}
@Override
public void onRegisterResult(RegisterResult result) {
if (result.errno == 0)
Toast.makeText(this, "注册成功", Toast.LENGTH_LONG).show();
else
Toast.makeText(this, result.errmsg, Toast.LENGTH_LONG).show();
}
@Override
public void onLoginResult(LoginResult result) {
if (result.errno == 0)
Toast.makeText(this, "登录成功", Toast.LENGTH_LONG).show();
else
Toast.makeText(this, result.errmsg, Toast.LENGTH_LONG).show();
}
@Override
public void onSetProgressBarVisibility(int visibility) {
relativeLayout.setVisibility(visibility);
}
}
MVP的模式大家应该知道了,在看看网络请求操作吧
1)请求第一步必然是URL地址的处理
public interface APIService {
@FormUrlEncoded
@POST("rest.php?a=auth")
Observable<LoginResult> login(@Field("user") String user, @Field("pswd") String pswd, @Field("type") String type);
@FormUrlEncoded
@POST("rest.php?a=register")
Call<RegisterResult> register(@Field("user") String user, @Field("pswd") String pswd, @Field("pswd2") String pswd2, @Field("type") String type);
}
URL地址以及参数的上传处理,
见这里有详细说明
@FormUrlEncoded
@Field
2)retrofit2基础公共类
public class RetrofitManager {
private static RetrofitManager instance;
private Retrofit retrofit;
private APIService service;
private String baseUrl = "这里大家写入一个自己的baseURL";
private RetrofitManager() {
//创建一个OkHttpClient并设置超时时间
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
httpClientBuilder.connectTimeout(5, TimeUnit.SECONDS);
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(httpClientBuilder.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//如果不使用rxjava可不必添加
.build();
service = retrofit.create(APIService.class);
}
public static RetrofitManager getInstance() {
if (instance == null) {
synchronized (RetrofitManager.class) {
instance = new RetrofitManager();
}
}
return instance;
}
public void login(String user, String pswd, Subscriber<LoginResult> subscriber) {
service.login(user, Md5.md5(pswd), "random")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
}
public void register(String user, String pswd, Callback<RegisterResult> callback) {
service.register(user, Md5.md5(pswd), Md5.md5(pswd), "random")
.enqueue(callback);
}
}
这其中也看到登录和注册请求有所不同,是因为一个使用rxjava,而另一个使用retrofit自带的一个call来处理数据,下面都有具体说明
1.rxjava
@FormUrlEncoded
@POST("rest.php?a=auth")
Observable<LoginResult> login(@Field("user") String user, @Field("pswd") String pswd, @Field("type") String type);
public void login(String user, String pswd, Subscriber<LoginResult> subscriber) {
service.login(user, Md5.md5(pswd), "random")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
}
BaseSubscriber类,因为项目中必然多次用到,不能用一次就编写
public abstract class BaseSubscribe<T> extends Subscriber<T> {
//用户重写使用,方便获取和发送数据
protected abstract void _onNext(T t);
protected abstract void _onError(Throwable e);
private Context context;
public BaseSubscribe(Context context) {
this.context = context;
}
@Override
public void onCompleted() {
Toast.makeText(context, "获取成功!", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
if (e instanceof SocketTimeoutException) {
Toast.makeText(context, "网络中断,请检查您的网络状态", Toast.LENGTH_SHORT).show();
} else if (e instanceof ConnectException) {
Toast.makeText(context, "网络中断,请检查您的网络状态", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "error:" + e.getMessage(), Toast.LENGTH_SHORT).show();
Log.i("error", e.getMessage());
_onError(e);
}
}
@Override
public void onNext(T t) {
_onNext(t);
}
}
因此在PresenterImpl实现类中的使用:
RetrofitManager.getInstance().login(user, pswd, new BaseSubscribe<LoginResult>(context) {
@Override
protected void _onNext(LoginResult result) {
loginView.onLoginResult(result);
loginView.onSetProgressBarVisibility(View.GONE);
}
@Override
protected void _onError(Throwable e) {
loginView.onSetProgressBarVisibility(View.GONE);
}
});
2.retrofit自带call与上述如出一辙,大家可自己模仿编写
这样子说明不知大家对MVP+Retrofit2+RxJava的使用有没有进一步理解,如果还有疑惑,那请再学习其他大神的讲解!!!