1, 前面两篇文章我们知道了怎么使用常用的四种标签,现在我们结合我们自己的项目中去简单的使用

  在我们搭建项目的时候,一般会创建自己的Application,在里面进行一些初始化如一些第三方的GreenDao、ShareSDK等等,再或者提供一些常用的属性初始化:例如初始化屏幕的宽高度、初始化SPUtils工具类等,所以我们可以创建App类继承自Application(这里我只写了简单的App对象创建,没有写其他的任何方法)

package com.qianmo.rxjavatext;import android.app.Application;/*** Created by Administrator on 2017/4/21 0021.* E-Mail:543441727@qq.com*/public class App extends Application {public static App instance;public static synchronized App getInstance() {return instance;}@Overridepublic void onCreate() {super.onCreate();instance = this;}
}

  一般情况下我们使用很多情况下会使用到上下文环境,而使用Activity的上下文环境会容易发生内存泄漏问题,即该Activity本应该被销毁,但因为外部类持有context对象的引用而导致无法回收Activity,所以这里我们一般使用App中的上下文,这时候我们要向所有的activity提供一个Application的上下文环境对象,再结合我们之前学习的Dagger2知识,先写一下AppModule提供对象的代码

package com.qianmo.rxjavatext.di;import com.qianmo.rxjavatext.App;import javax.inject.Singleton;import dagger.Module;
import dagger.Provides;/*** Created by Administrator on 2017/4/21 0021.* E-Mail:543441727@qq.com*/@Module
public class AppModule {public final App application;public AppModule(App application) {this.application = application;}@Provides@SingletonApp provideApplicationContext() {return application;}
}

  很简单,就是在创建AppModule对象的时候将App对象传递进来,然后添加provideApplicationContext暴露app对象出去,再来看看AppComponent类

package com.qianmo.rxjavatext.di;import com.qianmo.rxjavatext.App;import javax.inject.Singleton;import dagger.Component;/*** Created by Administrator on 2017/4/21 0021.* E-Mail:543441727@qq.com*/
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {//向下层提供上下文环境App getContext();}

  这里可能大家有个疑问App getContext();这句代码是干什么的,我们知道Activity中有可能要使用到App上下文环境(虽然这个方法不一定能用到,但是我们还是准备着),这里就是给下层提供这个对象的。那么我们需要在App初始化这个AppComponent对象了

public class App extends Application {public static App instance;public static AppComponent appComponent;public static synchronized App getInstance() {return instance;}@Overridepublic void onCreate() {super.onCreate();instance = this;}public static AppComponent getAppComponent() {if (appComponent == null) {appComponent = DaggerAppComponent.builder().appModule(new AppModule(instance)).build();}return appComponent;}
}

  那么有同学就会有这个疑问什么叫“下层”,用什么表示上下层关系,这里给出的解释是当另一个Activity中的module也想拥有我们的上下文application对象呢?是还要想我们的AppModule一样吗?nonono,这是我们使用dependencies,首先创建Activity的Module,这个类很简单就是提供我们的activity对象,所以代码如下

package com.qianmo.rxjavatext.di;import android.app.Activity;import com.qianmo.rxjavatext.di.scope.ActivityScope;import javax.inject.Singleton;import dagger.Module;
import dagger.Provides;/*** Created by Administrator on 2017/4/21 0021.* E-Mail:543441727@qq.com*/
@Module
public class ActivityModule {private Activity mActivity;public ActivityModule(Activity mActivity) {this.mActivity = mActivity;}@Provides@ActivityScopeActivity provideActivity() {return mActivity;}
}

  这里的@ActivityScope就是我们上一篇学习的自定义Scope注解标签,没什么难的,再看看我们的ActivityComponent

package com.qianmo.rxjavatext.di;import android.app.Activity;import com.qianmo.rxjavatext.MainActivity;
import com.qianmo.rxjavatext.di.scope.ActivityScope;import dagger.Component;/*** Created by Administrator on 2017/4/21 0021.* E-Mail:543441727@qq.com*/
@ActivityScope
@Component(dependencies = AppComponent.class,modules = ActivityModule.class)
public interface ActivityComponent {//将当前的activity暴露出去Activity getActivity();void inject(MainActivity mainActivity);
}

  dependencies 关键字就是这样使用的 ,例如我们创建student对象,需要App的对象(当然这个需求在现实中是不成立的),我们就可以这样写Module

package com.qianmo.rxjavatext.di;import android.app.Activity;
import android.content.Context;import com.qianmo.rxjavatext.Student;
import com.qianmo.rxjavatext.di.scope.ActivityScope;import javax.inject.Singleton;import dagger.Module;
import dagger.Provides;/*** Created by Administrator on 2017/4/21 0021.* E-Mail:543441727@qq.com*/
@Module
public class ActivityModule {private Activity mActivity;public ActivityModule(Activity mActivity) {this.mActivity = mActivity;}@Provides@ActivityScopeActivity provideActivity() {return mActivity;}@ProvidesStudent provideStudent(App app) {return new Student(app);}
}

  我们按Ctrl+F9编译一下,发现我们的程序可以编译过来,正常的话不是应该报错误说App没有注入对象吗,为什么这里是可以运行,这就是dependencies 关键字的用法了,这里我们使用的是AppComponent中的getContext方法的app对象了。

  OK,这里我们在activity中开始调用试试创建Student对象,看看能不能拿到值

package com.qianmo.rxjavatext;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;import com.jakewharton.rxbinding.view.RxView;
import com.jakewharton.rxbinding.widget.RxCompoundButton;
import com.qianmo.rxjavatext.di.ActivityComponent;
import com.qianmo.rxjavatext.di.ActivityModule;
import com.qianmo.rxjavatext.di.DaggerActivityComponent;import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;import javax.inject.Inject;import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.schedulers.Schedulers;public class MainActivity extends AppCompatActivity {//需要一个Student对象@InjectStudent mStudent;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initInject();}//开始注解public void initInject() {getActivityComponent().inject(this);}protected ActivityComponent getActivityComponent() {return DaggerActivityComponent.builder().appComponent(App.getAppComponent()).activityModule(getActivityModule()).build();}protected ActivityModule getActivityModule() {return new ActivityModule(this);}
}

  运行一下看一下打印结果

04-21 05:36:19.510 2646-2646/com.qianmo.rxjavatext I/System.out: 打印上下文对象呀com.qianmo.rxjavatext.App@34877b0

  没问题,说明我们的程序没问题,但是在实际项目中我们都是要编写BaseActivity的,所以我们需要在BaseActivity中这样写

public abstract class BaseActivity<T extends BasePresenter> extends AppCompatActivity implements BaseView {@Injectprotected T mPresenter;protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(getLayout());initInject();if (mPresenter != null)mPresenter.attachView(this);App.getInstance().addActivity(this);initEventAndData();}@Overrideprotected void onStart() {super.onStart();}@Overrideprotected void onDestroy() {super.onDestroy();}/*** 添加注解*/protected abstract void initInject();protected abstract int getLayout();protected abstract void initEventAndData();protected ActivityComponent getActivityComponent(){return  DaggerActivityComponent.builder().appComponent(App.getAppComponent()).activityModule(getActivityModule()).build();}protected ActivityModule getActivityModule(){return new ActivityModule(this);}
}

  这里的BaseView和BasePresenter都是我们的MVP的基类,里面很简单的没有说明代码的,我们在具体的activity中怎么使用呢?首先创建MainActivity,在这里调用 mPresenter.attachView(new MainView())方法

package com.qianmo.rxjavatext.mvp.view;import com.qianmo.rxjavatext.R;
import com.qianmo.rxjavatext.base.BaseActivity;
import com.qianmo.rxjavatext.mvp.presenter.MainPresenterImpl;/*** Created by Administrator on 2017/4/21 0021.* E-Mail:543441727@qq.com*/public class SecondActivity extends BaseActivity<MainPresenterImpl> {@Overridepublic void showError(String msg) {}@Overridepublic void useNightMode(boolean isNight) {}@Overrideprotected void initInject() {getActivityComponent().inject(this);}@Overrideprotected int getLayout() {return R.layout.activity_main;}@Overrideprotected void initEventAndData() {mPresenter.attachView(new MainView());}
}

  再看看重要的MainPresenterImpl类

package com.qianmo.rxjavatext.mvp.presenter;import android.content.Context;
import android.widget.Toast;import com.qianmo.rxjavatext.App;
import com.qianmo.rxjavatext.base.BasePresenter;
import com.qianmo.rxjavatext.mvp.view.MainView;import javax.inject.Inject;import rx.Observable;
import rx.Subscriber;
import rx.Subscription;/*** Created by MVPHelper on 2016/11/08*/public class MainPresenterImpl implements BasePresenter<MainView> {private Context context;@Injectpublic MainPresenterImpl(App app) {this.context = app;}@Overridepublic void attachView(MainView view) {Toast.makeText(context, "获取到值了", Toast.LENGTH_SHORT).show();}@Overridepublic void detachView() {}
}

  在这里最关键的标注了构造函数MainPresenterImpl,这样我们就注解到了该presenter对象了,看一下效果,ok,基本上我们就是在MVP工程下注解presenter对象了,关键是封装!!!(如果你封装很好了,后面开发使用就很简单,而且也不用单独的写一些Module、component类)

  最后,说一下使用范围对于中小型的项目真心没必要使用Dagger2,还有如果你是Android负责人的话,你还要考虑一下你的Android同事他们上手Dagger2的情况,所以这里还是要试开发情况定(感觉这一片还是没和大家在项目封装的时候讲清楚啊,关键是封装是Dagger两个都是不容易上手的,麻蛋,自己思路写的也混乱了,祝大家早日拖坑)。

转载于:https://www.cnblogs.com/wjtaigwh/p/6744939.html

Android -- 带你从源码角度领悟Dagger2入门到放弃(三)相关推荐

  1. Android -- 带你从源码角度领悟Dagger2入门到放弃(一)

    1,以前的博客也写了两篇关于Dagger2,但是感觉自己使用的时候还是云里雾里的,更不谈各位来看博客的同学了,所以今天打算和大家再一次的入坑试试,最后一次了,保证最后一次了. 2,接入项目 在项目的G ...

  2. 带你从源码角度分析ViewGroup中事件分发流程

    序言 这篇博文不是对事件分发机制全面的介绍,只是从源码的角度分析ACTION_DOWN.ACTION_MOVE.ACTION_UP事件在ViewGroup中的分发逻辑,了解各个事件在ViewGroup ...

  3. Redis源码阅读,从入门到放弃

    作为后端工程师,我们在面试和工作中都会用到 Redis,特别是大型互联网公司面试时,不仅要求面试者能简单使用 Redis,还要求懂 Redis 源码层面的实现原理,具备解决常见问题的能力.可以说,熟练 ...

  4. 【转】Android事件分发机制完全解析,带你从源码的角度彻底理解(下)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9153761 记得在前面的文章中,我带大家一起从源码的角度分析了Android中Vi ...

  5. [学习总结]7、Android AsyncTask完全解析,带你从源码的角度彻底理解

    我们都知道,Android UI是线程不安全的,如果想要在子线程里进行UI操作,就需要借助Android的异步消息处理机制.之前我也写过了一篇文章从源码层面分析了Android的异步消息处理机制,感兴 ...

  6. Android事件分发机制完全解析,带你从源码的角度彻底理解(上)

    <div id="container">         <div id="header">     <div class=&qu ...

  7. 从源码角度解析Android中APK安装过程

    从源码角度解析Android中APK的安装过程 1. Android中APK简介 Android应用Apk的安装有如下四种方式: 1.1 系统应用安装 没有安装界面,在开机时自动完成 1.2 网络下载 ...

  8. 【Android 插件化】Hook 插件化框架 ( 从源码角度分析加载资源流程 | Hook 点选择 | 资源冲突解决方案 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  9. 从源码角度看Android系统Launcher在开机时的启动过程

    Launcher是Android所有应用的入口,用来显示系统中已经安装的应用程序图标. Launcher本身也是一个App,一个提供桌面显示的App,但它与普通App有如下不同: Launcher是所 ...

最新文章

  1. 在Linux中如何禁止用户登录
  2. 在wsl中运行开源项目tinyhttpd遇到的问题
  3. Go会接替Java,成为下一个企业级编程语言吗?
  4. vc2010中设置ipch与sdf的位置
  5. boost::ptr_list相关的测试程序
  6. 汇编语言-007(ADD_SUB_NEG 、 PUSH和POP指令应用 、 AND,OR,XOR使用 、 条件跳转应用)
  7. 单例模式之恶汉模式(详解)
  8. python爬虫验证码的识别_Python爬虫识别验证码
  9. 14怎么敷铜不了_诗懿教你如何避开这十大敷面膜误区,护肤效果可翻倍!
  10. 二叉树节点为某一值的路径
  11. vue props 多类型_一个TypeScript简例,以及Vue支持TS的一些些事儿
  12. PASS云计算书简介——接近完美的模式
  13. CSDN-markdown编辑器语法——背景色
  14. redis 返回 key 的剩余的过期时间(RedisTemplate封装PTTL 命令)
  15. android studio 配置+安装
  16. Linux中__setup()实现原理以及源码分析
  17. C语言实现浮点数大小端转化
  18. 2.判断一个字符串是否为另外一个字符串旋转之后的字符串。例如:给定s1 =AABCD和s2 = BCDAA,返回1给定s1=abcd和s2=ACBD,返回0.AABCD左旋一个字符得到ABCD
  19. kindle来袭,当当错过的那些机会
  20. docker虚拟技术redis dockerfile源码安装、RDM绿色压缩包

热门文章

  1. ./和../和/三种路径的区别
  2. 亚马逊是如何进行软件开发的
  3. Android中RecyclerView嵌套RecyclerView或嵌套ListView
  4. Java基础学习总结(11)——重载与重写
  5. 【机器学习】--隐含马尔科夫模型从初识到应用
  6. WebApi接口安全认证——HTTP之摘要认证
  7. CRM 客户端程序开发:获取表单界面上各种字段的值及其他属性
  8. eclipse插件之easyshell
  9. SQL2008代理作业出现错误: c001f011维护计划创建失败的解决方法
  10. 域控制器建立以及一般配置