mvp+rxjava2.0+retrofit2.0+realm

6 篇文章 0 订阅
3 篇文章 0 订阅

本文属于技术的合并,所以不会对mvp、rxjava等的技术进行初始使用的讲解。建议对这些技术有一定基础后查看。

先看依赖

先在根目录(工程目录)build.gradle添加realm的插件安装

buildscript {  
    repositories {  
        jcenter()  
    }  
    dependencies {  
        classpath "io.realm:realm-gradle-plugin:2.3.0"
    }  

再在app的gradle中添加

android {
    apply plugin: 'realm-android'
}
dependencies {
    implementation 'io.reactivex.rxjava2:rxjava:2.1.1'
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'

    implementation 'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.retrofit2:converter-scalars:2.3.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'//配合rxjava2
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'

    implementation 'com.squareup.okhttp3:logging-interceptor:3.8.1'//拦截器
}

1.mvp包分类:

Contact:(1)view接口(2)presenter接口    ----作为接口统筹调用,以供v层和p层的互相调用。也方便开发者理清逻辑

Activity:继承view接口持有presenter 的接口--持有接口不持有presenter实例,以保证层与层调用皆以接口调用。

----对应v层


presernter:继承presenter接口--网络或数据库耗时操作时使用rxjava2.0启动异步

 ----对应P层

 

model: (1)DBhelper--Realm(2)RetrofitService--retrofit2.0

数据库耗时操作和网络请求都在p层调用。 

 ----对应M层

2.具体代码:

以登录为例子:

先看Contact:

public interface LoginContact {
    interface view extends BaseView {
        void loginSuccess();
    }

    interface presenter extends BasePresenter {
        /**
         * 登录
         */
        void login(LoginRequest request);
    }
}

如果熟悉MVP的会发现这里没有Model的接口。因为使用Retrofit的缘故,将网络请求Model是直接用RetroditService文件来直接调用,而数据库用的Realm,数据库存取用DBHelper。即Model层是共用两种文件:

  1. Retrofit的网络请求实体类
  2. Realm的数据存取实体类

写到persenter的实体类请求则会清晰明了些。如下:

public class LoginPresenter extends BasePresenterImpl<LoginContact.view>
        implements LoginContact.presenter {

    public LoginPresenter(LoginContact.view view) {
        super(view);
    }

    @Override
    public void login(LoginRequest request) {
        Api.getInstance().login(GsonUtil.GsonString(request))
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(new Consumer<Disposable>() {
                    @Override
                    public void accept(Disposable disposable) throws Exception {
                        addDisposable(disposable);
                        view.showLoadingDialog("请求发起");
                    }
                })
                .map(new Function<LoginResponse, LoginResponse>() {
                    @Override
                    public LoginResponse apply(final LoginResponse baseBean) throws Exception {
                        DbHelper.getDbHelper().saveBaseInfo(baseBean);//保存登录数据
                        return baseBean;
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<LoginResponse>() {
                    @Override
                    public void accept(LoginResponse baseBean) throws Exception {
                        view.loginSuccess();
                        view.dismissLoadingDialog();
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        view.dismissLoadingDialog();
                        view.showToast("失败:" + throwable.getMessage());
                        ExceptionHelper.handleException(throwable);
                    }
                });;
    }


}

请求完毕后如果需要数据存储或数据的中转处理,建议是在转换回主线程前用map处理返回数据,并且用DbHelper的方法进行数据存储。然后再回到主线处理界面上的事项。

这样看从view层查看到presenter层就可以直观明了的查看到 请求和返回 的处理逻辑。

那么我们现在来了解下rxjava2.0和retrofit2.0是怎么结合

public class BaseApiImpl implements BaseApi {
    private volatile static Retrofit retrofit = null;
    protected Retrofit.Builder retrofitBuilder = new Retrofit.Builder();
    protected OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder();

    public BaseApiImpl(String baseUrl) {
        retrofitBuilder.addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(new GsonBuilder()
                        .setLenient()
                        .create()
                ))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(httpBuilder.addInterceptor(getLoggerInterceptor()).build())
                .baseUrl(baseUrl);
    }

    /**
     * 构建retroft
     *
     * @return Retrofit对象
     */
    @Override
    public Retrofit getRetrofit() {
        if (retrofit == null) {
            //锁定代码块
            synchronized (BaseApiImpl.class) {
                if (retrofit == null) {
                    retrofit = retrofitBuilder.build(); //创建retrofit对象
                }
            }
        }
        return retrofit;

    }


    @Override
    public OkHttpClient.Builder setInterceptor(Interceptor interceptor) {
        return httpBuilder.addInterceptor(interceptor);
    }

    @Override
    public Retrofit.Builder setConverterFactory(Converter.Factory factory) {
        return retrofitBuilder.addConverterFactory(factory);
    }

    /**
     * 日志拦截器
     * 将你访问的接口信息
     *
     * @return 拦截器
     */
    public HttpLoggingInterceptor getLoggerInterceptor() {
        //日志显示级别
        HttpLoggingInterceptor.Level level = HttpLoggingInterceptor.Level.HEADERS;
        //新建log拦截器
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Log.d("ApiUrl", "--->" + message);
            }
        });
        loggingInterceptor.setLevel(level);
        return loggingInterceptor;
    }
}

BaseApiImpl是用来给Retrofit实体类工具 继承的基础类,这里将retrofit的实例创建好,并且可以在此做基础的日志拦截。下面为实体类工具代码:

public class Api extends BaseApiImpl {
    private static Api api = new Api(RetrofitService.BASE_URL);

    public Api(String baseUrl) {
        super(baseUrl);
    }


    public static RetrofitService getInstance() {
        return api.getRetrofit().create(RetrofitService.class);
    }
}

在我们上面presenter的登录调用就用了Api.getInstance()方法。目的就是拿到RetrofitService的retrofit实体类,进行网络的调用。

下面来看下RetrofitService代码:

public interface RetrofitService {

    String BASE_URL = "http://IP:port/api/";


    @GET("self/getUserSelfInfo")
    Observable<LoginResponse> login(@Body String request);

}

@GET和@Body都是Retrofit的使用方式。而Observable就是rxjava的订阅类,此类可以进行异步的发起。

我们在写完这些后,以后有新的网络请求只需要在RetrofitService这个文件中添加对应的请求。就可以在presenter中直接请求了。

这样就对以后的代码编写节约了很多时间。

现在我们再看下Realm的使用:

public class DbHelper {
    public static volatile DbHelper dbHelper;

    public static DbHelper getDbHelper(){
        if(dbHelper ==null){
            synchronized (DbHelper.class){
                if(dbHelper == null){
                    dbHelper =new DbHelper();
                }
            }
        }
        return dbHelper;
    }

    public static RealmResults<BaseInfo> getBaseInfos(){
        return Realm.getDefaultInstance().where(BaseInfo.class).findAll();
    }
    public void saveBaseInfo(final LoginResponse baseBean){
        Realm.getDefaultInstance().executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                BaseInfo ba = new BaseInfo();
                ba.setName(baseBean.getData().getUserName());
                ba.setUserId(baseBean.getData().getUserId());
                realm.copyToRealm(ba);
            }
        });
    }
}

除去初始的Realm配置。直接看DbHepler,使用单例保证dbHelper不会在同一时间被不同线程调用,再将添加所需要的数据库操作方法即可。

 

这样就有完整的基础框架。如果大家对这样的代码感兴趣的话可以点击下方下载。

mvp+rxjava2+retrofit2.0+realm基础代码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值