商业级开发框架(MVP+RxJava+Retrofit+GreenDAO)详解

转载请注明出处:http://blog.csdn.net/tyhj_sf/article/details/52822514

前言

本文不会逐个讲解MVP、Rxjava、Retrofit、GreenDAO的使用方法,而是结合app的用户注册登录功能的DEMO代码综讲解实际开发中如何综合使用。相信你认真分析和运行这个Demo之后,就可以上手用在你的项目中了。
关于MVP模式的详细介绍,可以参见:
MVC、MVP、MVVM深入理解与使用
各层之间的解耦使用Rxjava,关于Rxjava的详细使用方法,强烈推荐:
给 Android 开发者的 RxJava 详解
网络的访问使用Retrofit关于Retrofit的使用方法,推荐:
Retrofit用法详解
数据库存取使用GreenDAO开源库,关于GreenDAO的简单使用可以参考:
GreenDAO 3.2官方给的例子
Android数据存储之GreenDao 3.0 详解

项目搭建

1.MVP模式的package 结构
这里写图片描述
2.在gradle文件添加项目使用的第三方包的依赖关系
修改project的build.gradle文件如下:
这里写图片描述
这里写图片描述

在Module的build.gradle中添加使用的包和插件:
这里写图片描述

修改的地方如下图:
这里写图片描述

MVP框架之View层

实现APP的用户注册功能,界面如下图:
这里写图片描述

layout文件就不贴出来了,整个DEMO的源码的链接我已经放在文章的结尾。

View层的相关类

这里写图片描述
这里我们以SignOnFragment类为例来说,SignOnFragment类本身是一个Fragment,我们把它当做MVP模式中V,activity用来控制组件的生存周期,这是Google官方推荐的用法,但是Fragment必须内嵌到activity中显示,并且fragmen的使用也使组件生存周期和组件间通信变得复杂。对于不太复杂的应用,其实我们完全可以把activity看做是MVP中的V,显示逻辑写在activity中丢弃fragment,这样看起来代码结构更简洁。

SignOnFragment类文件代码如下:

public class SignOnFragment extends android.app.Fragment implements SignOnFragmentInterface {

    private EditText mUsername;
    private EditText mUserPassword1;
    private EditText mUserPassword2;
    private EditText mEmailAddress;
    private Button mRegister;
    private ProgressDialog progressDialog;

    private SignOnLogic signOnLogicInterface;

    /**供系统调用*/
    public SignOnFragment() {
        // Required empty public constructor
    }

    public static SignOnFragment newInstance(){
        return new SignOnFragment();
    }

    public SignOnLogic getSignOnLogicInterface() {
        return signOnLogicInterface;
    }

    public void setSignOnLogicInterface(SignOnLogic signOnLogicInterface) {
        this.signOnLogicInterface = signOnLogicInterface;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_sign_on, container, false);
        mUsername=(EditText) view.findViewById(R.id.register_name);
        mEmailAddress=(EditText) view.findViewById(R.id.register_email);
        mUserPassword1=(EditText)view.findViewById(R.id.register_password1);
        mUserPassword2=(EditText)view.findViewById(R.id.register_password2);
        mRegister =(Button)view.findViewById(R.id.register_register);
        mRegister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                signOnLogicInterface.authority(getSignOnInfo());
            }
        });
        progressDialog=new ProgressDialog(getActivity());
        return view;
    }

    @Override
    public void onDestroy() {
        if (progressDialog!=null){
            progressDialog.dismiss();
        }
        super.onDestroy();
    }

    @Override
    public void onDetach() {
        super.onDetach();

    }

    void updateView(Map<String, Object> map){

    }

    @Override
    public Map<String, Object> getSignOnInfo(){
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("mUserName",mUsername.getText().toString());
        map.put("mUserPassword1",mUserPassword1.getText().toString());
        map.put("mUserPassword2",mUserPassword2.getText().toString());
        map.put("mEmailAddress",mEmailAddress.getText().toString());
        return map;
    }

    @Override
    public void showCheckError(String result) {
        Toast.makeText(getActivity(),result,Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showErrorByToast(String result) {
        Toast.makeText(getActivity(),result,Toast.LENGTH_SHORT).show();
    }

    @Override
    public void showProgressDialog() {
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage("正在注册....");
        progressDialog.show();
    }

    @Override
    public void dismissProgressDialog() {
        progressDialog.dismiss();
    }

    @Override
    public void gotoSignInView() {
        getActivity().startActivity(new Intent(getActivity(), SignInActivity.class));
    }
}

只需坚持一条原则,View层代码中不含有任何处理逻辑及model的逻辑,而只有显示逻辑。

MVP框架之Model层

model层我们在这里只定义一个实体类:User,其代码如下:

package com.example.mvp_demo.model;

import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.NotNull;
import org.greenrobot.greendao.annotation.Generated;

/**
 *
 * Created by hasee on 2016/8/22.
 */
@Entity
public class User extends BasicEntity {

    @Id(autoincrement = true)
    public Long id;
    @NotNull
    public String mUsername;
    public String mUserPassword;
    public String mEmailAddress;

    public User(){

    }

    @Generated(hash = 594399851)
    public User(Long id, @NotNull String mUsername, String mUserPassword, String mEmailAddress) {
        this.id = id;
        this.mUsername = mUsername;
        this.mUserPassword = mUserPassword;
        this.mEmailAddress = mEmailAddress;
    }

    @Override
    public String toString() {
        return super.toString()+",[mUsername]="+mUsername+",[mUserPassword]="+mUserPassword+",[mEmailAddress]="+mEmailAddress;
    }

    @Override
    public boolean equals(User obj) {
        return  mUsername.equals(obj.mUsername);
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getMUsername() {
        return this.mUsername;
    }

    public void setMUsername(String mUsername) {
        this.mUsername = mUsername;
    }

    public String getMUserPassword() {
        return this.mUserPassword;
    }

    public void setMUserPassword(String mUserPassword) {
        this.mUserPassword = mUserPassword;
    }

    public String getMEmailAddress() {
        return this.mEmailAddress;
    }

    public void setMEmailAddress(String mEmailAddress) {
        this.mEmailAddress = mEmailAddress;
    }
}

由于我们使用了GreenDao数据库ORM框架,因此实际上我们只需要定义清楚如下图红线框部分,注解清楚哪些成员变量我们需要映射到数据库中,其他的代码在gradle时,有GreenDao框架自动生成:
这里写图片描述

MVP框架之Presenter层

最关键的部分来了。

对于注册功能,presenter层类有如下两个:
这里写图片描述

先贴SignOnLogicImpl类的代码:

public class SignOnLogicImpl implements SignOnLogic {

    public SignOnFragmentInterface signOnFragmentInterface;

    public SignOnLogicImpl(SignOnFragmentInterface signOnFragmentInterface) {
        this.signOnFragmentInterface = signOnFragmentInterface;
    }

    public void setSignOnFragmentInterface(SignOnFragmentInterface signOnFragmentInterface) {
        this.signOnFragmentInterface = signOnFragmentInterface;
    }

    public SignOnFragmentInterface getSignOnFragmentInterface() {
        return signOnFragmentInterface;
    }

    protected boolean checkInput(Map<String, Object> userInfoMap) {
        String inputInfo = userInfoMap.get("mUserName").toString();
        String checkResult = null;
        if (inputInfo.trim().length() == 0) {
            checkResult = "用户名不能为空";
        } else if (inputInfo.length() < 6) {
            checkResult = "用户名太短";
        } else if (inputInfo.length() > 30) {
            checkResult = "用户名太长";
        } else if (!userInfoMap.get("mEmailAddress").toString().matches("[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}")) {
            checkResult = "邮箱格式错误,请检查";
        } else if (userInfoMap.get("mUserPassword1").toString().length() < 6) {
            checkResult = "密码太短";
        } else if (userInfoMap.get("mUserPassword1").toString().length() > 30) {
            checkResult = "密码太长";
        } else if (!userInfoMap.get("mUserPassword1").toString().equals(userInfoMap.get("mUserPassword2").toString())) {
            checkResult = "两次输入的密码不一致,请重新输入";
        }
        if (checkResult != null) {
            signOnFragmentInterface.showCheckError(checkResult);
            return false;
        }
        return true;
    }

    @Override
    public void authority(Map<String, Object> userInfoMap) {
//        boolean isSuccess=false;
        if (!checkInput(userInfoMap)) {
            return ;
        }
        final User user = new User();
        user.mUsername = userInfoMap.get("mUserName").toString();
        user.mUserPassword = userInfoMap.get("mUserPassword1").toString();
        user.mEmailAddress = userInfoMap.get("mEmailAddress").toString();
        signOnFragmentInterface.showProgressDialog();

        new Retrofit.Builder()
                .baseUrl(MyApplication.BASIC_URL)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(Server.class)
                .uploadUser(user)   //上传注册信息
                .doOnNext(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        if (s.equals("success")) {
                            //保存用户注册信息到客户端数据库
                            GreenDaoManager
                                    .getInstance()
                                    .getmDaoSession()
                                    .getUserDao()
                                    .insert(user);
                            Log.d("数据库测试", "保存user成功");
                        }
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        signOnFragmentInterface.dismissProgressDialog();
                    }

                    @Override
                    public void onError(Throwable e) {
                        signOnFragmentInterface.dismissProgressDialog();
                        signOnFragmentInterface.showErrorByToast("网络发生错误:" + e.toString());
                    }

                    @Override
                    public void onNext(String s) {
                        if (s.equals("success")) {
                            //界面跳转到
                            signOnFragmentInterface.gotoSignInView();
                        } else {
                            signOnFragmentInterface.showErrorByToast("服务端响应错误");
                        }
                    }
                });
    }
}

这里protected boolean checkInput(Map<String, Object> userInfoMap)无非是对用户输入信息进行格式校验。
这里的public void authority(Map<String, Object> userInfoMap)用于向服务器端请求并向界面输出服务端认证结果。

我们着重看这部分代码:

 new Retrofit.Builder()
                .baseUrl(MyApplication.BASIC_URL)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(Server.class)
                .uploadUser(user)   //上传注册信息
                .doOnNext(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        if (s.equals("success")) {
                            //保存用户注册信息到客户端数据库
                            //。。。。。省略。。。。。
                        }
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                       // 。。。。。省略。。。。。
                    }

                    @Override
                    public void onError(Throwable e) {
//。。。。。省略。。。。。
                    }

                    @Override
                    public void onNext(String s) {
                      // 。。。。。省略。。。。。。
                        }
                    }
                });

由于Retrofit库已经为RxJava做了适配,这里我把Retrofit访问服务器的接口函数与RxJava的Observable结合起来,即uploadUser()函数返回Observable<String>类型对象,实现了很流畅的函数响应式编程。
Retrofit访问网络的接口如下:
这里写图片描述
如果不使用RxJava,那么Retrofit的网络接口定义应该是这样的:

 @GET("account")
    Call<String> uploadUser(@Query("username") User user);

项目整体上已经粗略讲解完毕。只看源码,不如亲自试试运行一个完整的DEMO理解得透彻!
附上源码下载链接:MVP+RxJava+Retrofit+GreenDao的Demo源码

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值