Android--MVP+Retrofit+Rxjava的实现

这一片博文 主要着眼于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 onFail(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 ~
谢谢 阅读

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MVP(Model View Presenter)其实就是一种项目的整体框架,能让你的代码变得更加简洁,说起框架大家可能还会想到MVC、MVVM。由于篇幅原因,这里我们先不讲MVVM,先来看一下MVC。其实Android本身就采用的是MVC(Model View Controllor)模式、其中Model指的是数据逻辑和实体模型;View指的是布局文件、Controllor指的是Activity。对于很多Android初学者可能会有这样的经历,写代码的时候,不管三七二十一都往Activity中写,当然我当初也是这么干的,根本就没有什么框架的概念,只要能实现某一个功能就很开心了,没有管这么多。当然项目比较小还好,一旦项目比较大,你会发现,Activity所承担的任务其实是很重的,它既要负责页面的展示和交互,还得负责数据的请求和业务逻辑之类的工作,相当于既要打理家庭,又要教育自己调皮的孩子,真是又当爹又当妈。。。那该怎么办呢?这时候Presenter这个继父来到了这个家庭。Presenter对Activity说,我来了,以后你就别这么辛苦了,你就好好打理好View这个家,我专门来负责教育Model这孩子,有什么情况我会向你反映的。这时Activity流下了幸福的眼泪,从此,Model、View(Activity)、Presenter一家三口过上了幸福的生活。。。好了磕个药继续,由于Presenter(我们自己建的类)的出现,可以使View(Activity)不用直接和Model打交道,View(Activity)只用负责页面的显示和交互,剩下的和Model交互的事情都交给Presenter做,比如一些网络请求、数据的获取等,当Presenter获取到数据后再交给View(Activity)进行展示,这样,Activity的任务就大大减小了。这便是MVP(Model 还是指的数据逻辑和实体模型,View指的是Activity,P就是Presenter)框架的工作方式。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值