您的位置:首页 > 移动开发 > Android开发

Android--MVP+Retrofit+Rxjava的实现

2017-08-29 19:29 591 查看
这一片博文 主要着眼于mvp框架和retrofit+rxjava的配合;以一个简单实例来实现用户的登录;

首先来看效果图:



重要的是功能,界面较为简单:

1.Mvp 实现login的总体框架

2.网络请求为 retrofit ,实现多层次封装

3.retrofit的请求和响应使用 rxjava 来实现

在看代码之前首先来看项目的整体架构:



作为业务逻辑和业务模型的model层 不仅仅可以放置javabean 部分业务逻辑接口可以放在这里 一个人而定

ok~ 下面 以代码为主导线开始剖析:

1.model层:

仅展示loginInfo代码 不做解释:

package com.example.houruixiang.mvp.model;

/**
* Created by houruixiang on 2017/8/28.
*/

public class LoginInfo {

private int errorcode;
private String message;
private DataBean data;

public int getErrorcode() {
return errorcode;
}

public void setErrorcode(int errorcode) {
this.errorcode = errorcode;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

public DataBean getData() {
return data;
}

public void setData(DataBean data) {
this.data = data;
}

public class DataBean {
private String flag;
private String stuname;
private String tel;
private String stuid;
private String photo;
private String idcard;
private String sex;
private String registered;
private String address;
private String km;
private String signname;
private String cartype;
private String pinscode;
private String zylx;

public String getFlag() {
return flag;
}

public void setFlag(String flag) {
this.flag = flag;
}

public String getStuname() {
return stuname;
}

public void setStuname(String stuname) {
this.stuname = stuname;
}

public String getTel() {
return tel;
}

public void setTel(String tel) {
this.tel = tel;
}

public String getStuid() {
return stuid;
}

public void setStuid(String stuid) {
this.stuid = stuid;
}

public String getPhoto() {
return photo;
}

public void setPhoto(String photo) {
this.photo = photo;
}

public String getIdcard() {
return idcard;
}

public void setIdcard(String idcard) {
this.idcard = idcard;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public String getRegistered() {
return registered;
}

public void setRegistered(String registered) {
this.registered = registered;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public String getKm() {
return km;
}

public void setKm(String km) {
this.km = km;
}

public String getSignname() {
return signname;
}

public void setSignname(String signname) {
this.signname = signname;
}

public String getCartype() {
return cartype;
}

public void setCartype(String cartype) {
this.cartype = cartype;
}

public String getPinscode() {
return pinscode;
}

public void setPinscode(String pinscode) {
this.pinscode = pinscode;
}

public String getZylx() {
return zylx;
}

public void setZylx(String zylx) {
this.zylx = zylx;
}
}
}


然后再这里 顺便定义了一个请求的接口:

(作为对retrofit 请求的二次封装的)

public interface RequestListener<T>{

void onSuccess(Response<T> response);
void onFa
f16a
il(Throwable t);
}


使用场景

比如:

//        call.enqueue(new Callback<T>() {
//            @Override
//            public void onResponse(Call<T> call, retrofit2.Response<T> response) {
//                mListener.onSuccess(response);
//            }
//
//            @Override
//            public void onFailure(Call<T> call, Throwable t) {
//                mListener.onFail(t);
//            }
//        });


在这里我们用rxjava在封装请求的响应暂时不用它;

2.presenter层:

presenter作为连接view和model的跳板在创建时候 最好先在其中创建一个总得接口IPresenter来定义方法 :

1. 管理字段属性的获取(比如登录需要用户名密码的存储等);

2. 请求成功失败之后的交互;

3. 还有队一些交互的处理(如加载框等)

那么来看IPresenter:

public interface IPresenter {
//想要得到什么

//请求完的交互
void onMainActiviy();
void onFailToast();

//交互的load设置
void showLoad();
void hideLoad();

}


接着看ApiClient,完成对retrofit的初始化和请求的初步封装:

1.初始化retrofit类和代理类:

private ApiClient() {

init();
//创建retrofit
//设置请求OkhhtpClient实例
mRetrofit = new Retrofit.Builder()
.baseUrl("....")
.client(mOkhttpClient) //设置请求OkhhtpClient实例
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}

public <T> T create(Class<T> service){

T t = mRetrofit.create(service);
return t;

}


然后 初始化拦截器(读取和延时时间等):

public void init(){

OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
//添加拦截器
if (builder.interceptors() != null){
builder.interceptors().clear();
}

builder
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {

Request request = chain.request();
//                        关于请求的打印日志
//                        String path = request.url().encodedFragment();
//                        String query = request.url().query();

return chain.proceed(request);
}
}).connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10,TimeUnit.SECONDS)
.writeTimeout(10,TimeUnit.SECONDS);

mOkhttpClient = builder.build();

}


最后是对请求的初步封装 这里我们用到rxjava:

   public <T> void onLoad(Observable<T> call, Subscriber<T> subscriber){

// call.enqueue(new Callback<T>() { // @Override // public void onResponse(Call<T> call, retrofit2.Response<T> response) { // mListener.onSuccess(response); // } // // @Override // public void onFailure(Call<T> call, Throwable t) { // mListener.onFail(t); // } // });
call.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);

}


由于retrofit提供了两套API所以rxjava 用起来比较方便;注意:注释部分为原始API下的封装;正文为rxjava的封装

接下来是注解API 的构建:

@FormUrlEncoded
@POST("/api/TimApi")
Observable<LoginInfo> getInfo(@Field("name")String name, @Field("key")String key,@Field("code")String code, @Field("data")String data);
}


然后在basePresenter中完成IPresenter ApiClient Retrofit-Service的初始化

public class BasePresenter {

public IPresenter mIp;
public ApiClient mApi;
public ReponseInfoApi mService;

public BasePresenter(IPresenter iPresenter) {
mApi = ApiClient.getInstance();
mIp = iPresenter;
mService = mApi.create(ReponseInfoApi.class);
}

public void load(String code,String data){
mIp.showLoad();
}

}


最后创建直接调用的LoginPresenter:

//    @Override
//    public void load(String code, String data) {
//        super.load(code, data);
//        Call<LoginInfo> info = mService.getInfo("APPAPI", "123456", code, data);
//
//
//
//        mApi.onLoad(info, new RequestListener<LoginInfo>() {
//            @Override
//            public void onSuccess(Response<LoginInfo> response) {
//                mIp.hideLoad();
//                LoginInfo.DataBean dataBean = response.body().getData();
//                String flag = dataBean.getFlag();
//                if (flag.equals("1")){
//
//                    mIp.onMainActiviy();
//                }else {
//                    mIp.onFailToast();
//                }
//            }
//
//            @Override
//            public void onFail(Throwable t) {
//                mIp.hideLoad();
//                mIp.onFailToast();
//            }
//        });
//
//
//    }

@Override
public void load(String code, String data) {
super.load(code, data);
Observable<LoginInfo> info = mService.getInfo("APPAPI", "123456", code, data);
mApi.onLoad(info, new Subscriber<LoginInfo>() {
@Override
public void onCompleted() {

}

@Override
public void onError(Throwable e) {

mIp.hideLoad();
mIp.onFailToast();

}

@Override
public void onNext(LoginInfo loginInfo) {

mIp.hideLoad();
LoginInfo.DataBean dataBean = loginInfo.getData();
String flag = dataBean.getFlag();
if (flag.equals("1")){

mIp.onMainActiviy();
}else {
mIp.onFailToast();
}

}
});
}


注意 注解为常规Api下的二次封装 正文为rxjava的请求响应封装;

2.View层:

先来看下activity的代码:

public class MainActivity extends AppCompatActivity implements IPresenter, View.OnClickListener {

private LoginPresenter mPresenter;
private TextView mUsername;
private TextView mPwd;
private Button mLogin;
private ImageView mLoad;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPresenter = new LoginPresenter(this);
initView();
initEvent();

}

private void initView() {
mUsername = (TextView) findViewById(R.id.username);
mPwd = (TextView) findViewById(R.id.pwd);
mLogin = (Button) findViewById(R.id.login);
mLoad = (ImageView) findViewById(R.id.load);
}

private void initEvent() {

mLogin.setOnClickListener(this);

}

@Override
public void onClick(View view) {

String user = mUsername.getText().toString().trim();
String pwd = mPwd.getText().toString().trim();
if (user == null || user.equals("") || pwd == null || pwd.equals("")){
return;
}

JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("tel",user);
jsonObject.put("pwd",pwd);
jsonObject.put("pname","北京");
} catch (JSONException e) {
e.printStackTrace();
}

String data = jsonObject.toString().replaceAll("\"(\\w+)\"(\\s*:\\s*)", "$1$2");

mPresenter.load("1001",data);

}

@Override
public void onMainActiviy() {
Toast.makeText(this,"success",Toast.LENGTH_SHORT).show();
}

@Override
public void onFailToast() {
Toast.makeText(this,"fail",Toast.LENGTH_SHORT).show();
}

@Override
public void showLoad() {
mLoad.setVisibility(View.VISIBLE);
}

@Override
public void hideLoad() {
mLoad.setVisibility(View.GONE);
}

}


作为mvp中只进行布局的activity 首先实现IPresenter 实现交互的方法和加载框的方法 然后在点击事件中自身作为参数来初始化LoginPresenter,在LoginPresenter中请求成功时候调用activity中提前定义好的hideLoad()和交互方法onMainActiviy();当请求失败时候调用hideLoad()和onFailToast();

这样一个简单的MVP+Retrofit+Rxjava就实现了 在之后 会主要交接下Rxjava ~

谢谢 阅读
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mvp