MVP模式本身相比于MVC模式就已经把View层和Controller层从Activity中进行了分离,将Model层和View层用Presenter层隔开,实现了初步的解耦。如果再加入Dagger2框架,就可以进一步解耦。
Dagger2使用的是依赖注入的思想,通过annotation注解的方式实现模块间的解耦,让“只写一小部分代码就可以使一切联系起来”成为了可能(削减了程序中的耦合问题)。Dagger是目前为止唯一一个可以生成完整模仿用户手写的可追踪的代码的DI框架。
Dagger2中有很多注解标签,其中一些及其功能列举如下:
@Module:Modules类里面的方法专门提供依赖,所以我们定义一个类,用@Module注解,这样Dagger在构造类的实例的时候,就知道从哪里去找到需要的依赖。
modules的一个重要特征是它们设计为分区并组合在一起(比如说,在我们的app中可以有多个组成在一起的modules)
@Provides:在modules中,我们定义的方法是用这个注解,以此来告诉Dagger我们想要构造对象并提供这些依赖。
@Singleton:当前提供的对象将是单例模式 ,一般配合@Provides一起出现
@Component:用于接口,这个接口被Dagger2用于生成用于模块注入的代码
@Inject:在需要依赖的地方使用这个注解。(你用它告诉Dagger这个 构造方法,成员变量或者函数方法需要依赖注入。这样,Dagger就会构造一个这个类的实例并满足他们的依赖。)
@Scope:Dagger2可以通过自定义注解限定注解作用域。
这个DEMO中用到的标签只有前五个,@Scope标签暂时没有用到。
下面直接上代码。首先申明一下,这个DEMO中用到的MVP就不加介绍了,有兴趣的朋友可以通过最后的传送门到我上一个帖子中查看。
在gradle文件中添加依赖(主要是apt、dagger、butterknife有关的代码):
apply plugin: 'com.android.application' apply plugin: 'com.neenbedankt.android-apt' android { compileSdkVersion 24 buildToolsVersion "24.0.2" defaultConfig { applicationId "com.example.itgungnir.testdagger" minSdkVersion 11 targetSdkVersion 24 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } buildscript { repositories { jcenter() } dependencies { classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:24.2.1' testCompile 'junit:junit:4.12' // Dagger的依赖包 apt 'com.google.dagger:dagger-compiler:2.2' compile 'com.google.dagger:dagger:2.2' // ButterKnife的依赖包 compile 'com.jakewharton:butterknife:5.1.1' }
MainActivity.java类中的代码:
public class MainActivity extends AppCompatActivity implements MainContract.IView { @Inject MainPresenter presenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化ButterKnife ButterKnife.inject(this); // Dagger注入 DaggerMainComponent.builder().mainModule(new MainModule(MainActivity.this)).build().inject(this); } @OnClick(R.id.btn) public void click() { onButtonClicked("Button Clicked!!!!"); } @Override public void onButtonClicked(String text) { presenter.onButtonClicked(MainActivity.this, text); } }
MainContract.java类中的代码:
public class MainContract { interface IView { void onButtonClicked(String text); } interface IModel { void onButtonClicked(Activity activity, String text); } interface IPresenter { void onButtonClicked(Activity activity, String text); } }
MainModel.java类中的代码:
public class MainModel implements MainContract.IModel { @Override public void onButtonClicked(Activity activity, String text) { Toast.makeText(activity, text, Toast.LENGTH_SHORT).show(); } }
MainPresenter.java类中的代码:
public class MainPresenter implements MainContract.IPresenter { private MainContract.IModel model; private MainContract.IView view; public MainPresenter(MainContract.IView view) { this.view = view; this.model = new MainModel(); } @Override public void onButtonClicked(Activity activity, String text) { model.onButtonClicked(activity, text); } }
MainModule.java类中的代码:
@Module public class MainModule { MainPresenter presenter; public MainModule(MainActivity activity) { presenter = new MainPresenter(activity); } @Provides @Singleton MainPresenter providesMainPresenter() { return presenter; } }
MainComponent.java接口中的代码:
@Singleton @Component(modules = MainModule.class) public interface MainComponent { void inject(MainActivity activity); }
最后贴一下MVP的传送门地址: