介绍

前面介绍了Dagger2,今天尝试自己的想法去应用了下,说实话很别扭,晚上睡觉思前想后这个的好处。总是有一种似懂非懂,感觉就是,让对象与对象之间产生了一中关联,多个module的provides(供给)的对象,通过1个Component联系起来,我尝试写了2个Demo,一个用了Dagger2,一个没有用,好处自己总结吧

MVP通过一个登陆Demo讲解

  • LoginAcitivity,view层,实现LoginContract.LoginMvpView接口(MVP中的Presenter通过接口形式调用view层)
  • LoginModule,Module层,提供了一个LoginApi的请求方法,返回LoginApi
  • LoginPresenter,Presenter层,继承LoginContract.LoginBasePresenter,内部通过login方法

MVP优点

  • 解耦View和Module(Activity再也不那么臃肿了)
  • 逻辑清晰,阅读代码只需要更具指定规则进行阅读(乱写的)
  • 其它自行体会

来个MVC和MVP图

项目结构

  • inject包所有的Dagger2的注入类
  • ApiModule类提供网络请求的提供的类,提供Retrofit
  • AppMoudle类通过Context和单利Toast
  • scope包自定义的scope
  • Api包放所有模块对应的Http请求
  • Contract包,mvp对用模块的view和presenter协议

开发逻辑

1:定义Application

public class App extends Application {private static Application app;
    public static AppComponent appComponent;
    @Override
    public void onCreate() {super.onCreate();
        app=this;
        //初始化全局AppComponent,主要对module里面单利和app处于一个生命周期
        appComponent = DaggerAppComponent.create();
    }public static Application getApplication(){return app;
    }public static Context getAppContext(){return app.getApplicationContext();
    }
}

2:AppComponent对应2个module

AppModule提供Context和Appcation,ApiModule提供网络请求Retrofit(单利)

@Singleton
@Component(modules = {AppModule.class, ApiModule.class})
public interface AppComponent {Context getContext();
    Application getApplication();
    Retrofit getRetrofit();
    Toast getToast();
}
/**
 * 访问网络的Module
 */
@Module
@Singleton
public class ApiModule {public static final String BASE_URL = "https://www.iqshw.com/";

    @Provides
    public Interceptor providesIntercepter() {return new Interceptor() {@Override
            public Response intercept(Chain chain) throws IOException {Request request = chain.request();
                Response response = chain.proceed(request);

                String chainControl = request.cacheControl().toString();
                if (TextUtils.isEmpty(chainControl)) {chainControl = "public, max-age=60, max-stale=240000";
                }return response.newBuilder().addHeader("Chain-Control", chainControl).removeHeader("Pragma").build();
            }};
    }@Provides
    public Cache providesCache(Context context) {File httpCacheFile = context.getExternalCacheDir().getAbsoluteFile();
        return new Cache(httpCacheFile, 1024 * 10 * 1024);
    }@Provides
    @Singleton
    public OkHttpClient providesOkHttpClient(Interceptor interceptor, Cache cache) {OkHttpClient client = new OkHttpClient.Builder().cache(cache).addInterceptor(interceptor).build();

        return client;
    }@Provides
    @Singleton
    public Retrofit providesRetrofit(OkHttpClient client) {Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).client(client).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();
        return retrofit;
    }}

3:LoginActivityCompenent创建,依赖于AppCompenent,自己的Module,LoginModule听LoginApi请求对象

注意LoginSingleton因为依赖了AppComponent,所以需要自己定义一个Scope

@LoginSingleton
@Component(modules = {LoginModule.class},dependencies = {AppComponent.class})
public interface LoginActivityComponent {void inject(LoginActivity activity);
}

4:MVP协议类LoginContract,所有的方法的业务方法都从这里创建

public interface LoginContract {interface LoginMvpView extends BaseMvpView{void loginSuccess(UserInfo userInfo);
        String getUser();
        String getPass();
    }abstract class LoginBasePresenter extends BasePresenter<LoginMvpView>{public abstract void login();
    }}

5:LoginPresenter定义

public class LoginPresenter extends LoginContract.LoginBasePresenter {@Inject
    public LoginApi loginApi;

    @Inject
    public LoginPresenter() {}@Override
    public void login() {String pass = mView.getPass();
        String user = mView.getUser();
        if (TextUtils.isEmpty(pass)) {mView.showToastMsg("请输入账号!");
        } else if (TextUtils.isEmpty(user)) {mView.showToastMsg("请输入密码!");
        } else {mView.showLoadDialog();
            Map<String, String> parameters = new HashMap<>();
            parameters.put("username", user);
            parameters.put("password", pass);
            parameters.put("enews", "login");
            parameters.put("lifetime", "315360000");

            loginApi.login(parameters).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<UserInfo>() {@Override
                        public void onCompleted() {mView.hideDialog();
                        }@Override
                        public void onError(Throwable e) {mView.hideDialog();
                            mView.showErrorMsg("请求网络失败!");
                            Log.d("wyz", "e::" + e.getMessage());
                        }@Override
                        public void onNext(UserInfo info) {Log.d("wyz", "请求数据:" + info);
                            mView.hideDialog();
                            mView.loginSuccess(info);
                        }});
        }}
}

6:LoginActivity,主要持有一个LoginPresenter对象即可

public class LoginActivity extends BaseActivity implements LoginContract.LoginMvpView{@Inject
    public LoginPresenter loginPresenter;
    @Inject
    public Toast toast;

    private EditText etPass;
    private EditText etUser;

    @Override
    public int getLayoutId() {return R.layout.activity_main;
    }@Override
    protected void initView() {progressDialog.setTitle("请稍后");
        progressDialog.setMessage("正在加载。。。");
    }@Override
    protected void initData() {//注入
        DaggerLoginActivityComponent.builder().appComponent(App.appComponent).build().inject(this);
        //设置view
        loginPresenter.setMvpView(this);
    }@Override
    protected void findView() {Button btLogin = findViewById(R.id.bt_login);
        etPass = findViewById(R.id.et_pass);
        etUser = findViewById(R.id.et_user);

        btLogin.setOnClickListener(new View.OnClickListener() {@Override
            public void onClick(View view) {loginPresenter.login();
            }});
    }@Override
    public void showLoadDialog() {progressDialog.show();
    }@Override
    public void showErrorMsg(String msg) {Log.d("wyz", "数据错误`消息:" + msg+" "+toast);
        toast.setText(msg);
        toast.show();
    }@Override
    public void showToastMsg(String msg) {Log.d("wyz", "数据消息:" + msg+" "+toast);
        toast.setText(msg);
        toast.show();
    }@Override
    public void hideDialog() {progressDialog.hide();
    }@Override
    public void loginSuccess(UserInfo userInfo) {toast.setText("UserInfo:" +userInfo);
        toast.show();
    }@Override
    public String getUser() {return etUser.getText().toString();
    }@Override
    public String getPass() {return etPass.getText().toString();
    }
}

这是我集成的Dagger2,大体流程是这样的

没用dagger2的RxJava+Retrofit+OkHttp+MVP,我就想知道哪些不舒服,发现有些地方还是有些便利的,例如创建网络请求的时候,只需要一个请求,我必须要写一个单利,createRetrofit,需要的参数,很麻烦,还是dagger2看的舒服些

public class RetrofitCreateHelper {public static final String BASE_URL = "https://www.iqshw.com/";
    private Retrofit retrofit;

    //郁闷还要写单利 dagger2 1个注解就oK
    private RetrofitCreateHelper(){createRetrofit();
    }public static RetrofitCreateHelper getHelper() {return Holder.holder;
    }public static class Holder{public static RetrofitCreateHelper holder=new RetrofitCreateHelper();
    }private  Interceptor getIntercepter() {return new Interceptor() {@Override
            public Response intercept(Chain chain) throws IOException {Request request = chain.request();
                Response response = chain.proceed(request);

                String chainControl = request.cacheControl().toString();
                if (TextUtils.isEmpty(chainControl)) {chainControl = "public, max-age=60, max-stale=240000";
                }return response.newBuilder().addHeader("Chain-Control", chainControl).removeHeader("Pragma").build();
            }};
    }private  Cache getCache(Context context) {File httpCacheFile = context.getExternalCacheDir().getAbsoluteFile();
        return new Cache(httpCacheFile, 1024 * 10 * 1024);
    }public  OkHttpClient getHttpClient(Interceptor interceptor, Cache cache) {OkHttpClient client = new OkHttpClient.Builder().cache(cache).addInterceptor(interceptor).build();

        return client;
    }private void createRetrofit(){//这里我感受到了Dagger2的好处了
        retrofit = new Retrofit.Builder().baseUrl(BASE_URL).client(getHttpClient(getIntercepter(),getCache(App.getAppContext())))//这里我感受到了Dagger2的好处了
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create()).addConverterFactory(GsonConverterFactory.create()).build();

    }public  <T> T createApi(Class<T> clazz) {return retrofit.create(clazz);
    }
}
//还是dagger2方便点
public class ToastUtil {private final Toast toast;

    public static Toast getToast(){return Hodler.holder.toast;
    }public static void showToast(String msg){Toast toast = getToast();
        toast.setText(msg);
        toast.show();
    }private ToastUtil(){toast = Toast.makeText(App.getAppContext(), "", Toast.LENGTH_SHORT);
    }private static class Hodler{public static ToastUtil holder=new ToastUtil();
    }
}

git代码地址

Dagger2之应用篇(Dagger2+RxJava+Retrofit+OkHttp+MVP)-第7章相关推荐

  1. Rxjava+retrofit+okHttp+mvp网络请求数据

    //Api类 public class Api {//http://api.svipmovie.com/front/columns/getVideoList.do?catalogId=40283481 ...

  2. Android使用RxJava+Retrofit2+Okhttp+MVP练习的APP

    Android使用RxJava+Retrofit2+Okhttp+MVP练习的APP 项目截图 这是我的目录结构 五步使用RxJava+Retrofit2+Okhttp+RxCache 第一步:导包 ...

  3. RxJava+Retrofit+OkHttp深入浅出-终极封装四(多文件下载之断点续传)

    http://blog.csdn.net/wzgiceman/article/details/52911503 转载于:https://www.cnblogs.com/zhangminghan/p/6 ...

  4. RxJava+Retrofit+MVP+Dagger2

    传说中的谷歌四件套,按顺序来哈~ 2017.2.20更新:对于用了一段时间的谷歌四件套的开发者们来说,基础应该都已经掌握的差不多了,但是四件套确实很博大精深,要想完全掌握,一是要学习使用技巧,二是要在 ...

  5. TLint for 虎扑体育 基于Dagger2+RxJava+Retrofit开发,采用MVP模式

    TLint 类别: 完整源码 打分: ★★★★★ 更新: 2016-05-12 09:54 大小: 6976 kb 开发环境: Android Studio 浏览: 484 次 下载: 83 次 项目 ...

  6. Dagger2实际应用篇

    前言 当前基于2.38.1源码整理出来的一篇实际应用: 现在回头看这篇文章,其实发现内容其实真的不错(对几年前自己啃源码的认可),但是之前的文章的结构性确实有点"呵呵",反正我回头 ...

  7. Retrofit+OKHttp+RxJava的使用

    什么是响应式编程   响应式编程是一种基于异步数据 流概念的编程模式.数据流就像一条河:它可以被观测,被过滤,被操作,或者为新的消费者与另外一 条流合并为一条新的流. 什么是RxJava RxJava ...

  8. Android RxJava+Retrofit+MVP 入门总结

    前言 RxJava+Retrofit+MVP的使用已经推出一段时间了,也一直想找个时间学习一下并且应用到接下来的项目中.趁放假这段时间仔细研究了一下,确实相比于其他框架的学习成本要高一些,不过功能实现 ...

  9. MVP+Dragger2+Rxjava2+Retrofit+OKhttp进行开发。

    MVP+Dragger2+Rxjava2+Retrofit+OKhttp框架已经流行很长时间,而且也必将成为未来android开发的趋势,在使用这个框架的过程中踩过很多坑, 所以想把我的经验告诉大家, ...

最新文章

  1. C++基类和派生类的析构函数
  2. 图解Android Studio 2.0安装步骤
  3. mysql与oracle在软件测试_Oracle和MySQL的一些简单命令对比
  4. python现有两个磁盘文件a和b_有两个磁盘文件A和B,各存放一行字母,今要求把这两个文件中的信息合并,输出到一个新文件C中。...
  5. 基于RANSAC的激光点云分割
  6. HDC.Cloud2021|开发者们都在谈的云原生到底长什么样?
  7. android系统功耗优化(2)---Android最佳实践之性能 - 电池续航时间优化
  8. 【luogu P2341 [HAOI2006]受欢迎的牛】 题解
  9. 知乎项目代码阅后总结
  10. Linux的文件的打包(tar方法)
  11. paip.获取当前实际北京时间API
  12. 上,下拉电阻的作用与计算
  13. 风尚云网学习-Linux/宝塔面板部署禅道开源系统
  14. 大数据告诉你,中国女人有多累
  15. Python excel数据处理之公式---openpyxl
  16. linux如何开启cpu热插拔,Linux走向真正的CPU热插拔支持
  17. 求2+22+222+2222+.....的N项之和
  18. 微信小程序 wx.getUserProfile返回的iv、encryptedData 解密获取不到openId的问题解决方案 openId无返回
  19. uniapp nvue页面 关闭输入法
  20. 锐龙r55600G和r55600x区别 r5 5600x和r5 5600g性能差别大吗

热门文章

  1. 【有利可图网】PS实战教程22:不借助插件滤镜的专业级PS商业修图技巧!
  2. dcrs 端口配ip_神州数码DCRS-5950 基本配置(一)
  3. 揭秘是什么?让开屏广告效益几何增长
  4. CSS入门---复合选择器学习与掌握
  5. uni-app swiper设置显示面板指示点的背景颜色与选中颜色
  6. 一灯大师,基于imx6ull点亮LED灯
  7. c语言结构体和联合体,C语言结构体和联合体
  8. AVR单片机烧写Arduino-bootloader
  9. BurpSuite 破解版(含注册机,无后门)下载注册详细教程
  10. 【开源项目】智慧软件园~江苏某软件园数字孪生可视化项目——开源工程及源码!