Dragger2是什么,我就不再说了。资料一堆,而且里面的注解什么意思,我推荐两篇文章,这两篇都是我精挑细选,一般的文章我是不推荐的。
http://android.jobbole.com/82694/
http://android.jobbole.com/82704/
http://android.jobbole.com/82705/ 有了基础的了解,来跟我helloworld吧。 第一步:配置依赖:
//如果你用了butterknife,那么这个com.neenbedankt.gradle.plugins就不用再次引入了 buildscript { repositories { mavenCentral() } dependencies { classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } } apply plugin: 'com.neenbedankt.android-apt' dependencies { apt 'com.google.dagger:dagger-compiler:2.0' compile 'com.google.dagger:dagger:2.0' // dagger2 // compile 'com.google.dagger:dagger-compiler:2.0.2' // dagger2 provided 'org.glassfish:javax.annotation:10.0-b28' } 123456789101112131415161718 123456789101112131415161718第二步:
走到这步我就遇到了一个坑,DaggerApplicationComponent这个类一直报找不到。
后来才知道,要rebuild一下,因为这个类是自动生成的。
解决了这个,然后跟着别人写代码,才算是入了点门。直到了写一个类的依赖注入,需要写三个东西: loginComponent LoginModel 额,是两个就行了。就像: AppComponent AppModule 这两个全局的。 然后怎么依赖给它的,我还没弄懂。遇到了三个错误:
Error:(6, 43) 错误: 找不到符号 符号: 类 DaggerAppComponent 位置: 程序包 com.chinaCEB.cebActivity.components 123 123 Error:(19, 10) 错误: com.chinaCEB.cebActivity.view.ILoginActivity cannot be provided without an @Provides-annotated method. com.chinaCEB.cebActivity.view.LoginActivity.loginPresenter [injected field of type: com.chinaCEB.cebActivity.presenter.LoginPresenter loginPresenter] com.chinaCEB.cebActivity.presenter.LoginPresenter.<init>(com.chinaCEB.cebActivity.view.ILoginActivity loginActivity) [parameter: com.chinaCEB.cebActivity.view.ILoginActivity loginActivity] 12345 12345每当我不懂dragger2的时候,就看一边资料。这样,真的很有帮助。 http://www.jianshu.com/p/c2feb21064bb
AppComponent: 生命周期跟Application一样的组件。可注入到自定义的Application类中,@Singletion代表各个注入对象为单例。
//component都是接口,到时候,dragger2会生成你的实现类。 //就像DaggerAppComponent 你写了AppComponent就会有DaggerAppComponent这个实现类 @Singleton @Component(modules = AppModule.class) public interface AppComponent { Context context(); // 提供Applicaiton的Context ThreadExecutor threadExecutor(); // 线程池 ApiService apiService(); // 所有Api请求的管理类 SpfManager spfManager(); // SharedPreference管理类 DBManager dbManager(); // 数据库管理类 } 12345678910111213141516 12345678910111213141516AppModule: 这里提供了AppComponent里的需要注入的对象。
//可以发现,AppModule和AppComponent 是对应的 //ThreadExecutor threadExecutor(); // 线程池 /*@Provides @Singleton ThreadExecutor provideThreadExecutor(JobExecutor jobExecutor) { return jobExecutor; } */ @Module public class AppModule { private final MyApplication application; public AppModule(MyApplication application) { this.application = application; } @Provides @Singleton Context provideApplicationContext() { return application; } @Provides @Singleton ThreadExecutor provideThreadExecutor(JobExecutor jobExecutor) { return jobExecutor; } @Provides @Singleton ApiService providesApiService(RetrofitManager retrofitManager) { return retrofitManager.getService(); } @Provides @Singleton SpfManager provideSpfManager() { return new SpfManager(application); } @Provides @Singleton DBManager provideDBManager() { return new DBManager(application); } } 12345678910111213141516171819202122232425262728293031323334353637383940414243444546 12345678910111213141516171819202122232425262728293031323334353637383940414243444546也就是AppComponent里面全都是对象,AppModule是它的实现。可是这些入参都是谁给的?
终于知道activity是怎么得到的了。
@Module public class ActivityModule { private final Activity activity; public ActivityModule(Activity activity) { this.activity = activity; } @Provides @ActivityScope Activity activity() { return this.activity; } } 然后: // 建议写在基类Activity里 protect ActivityModule getActivityModule(){ return new ActivityModule(this); } 123456789101112131415161718192021 123456789101112131415161718192021搞了一天,终于搞定了。dragger2. 我知道我可以的。哼哼。 我现在知道完整的dragger2步骤了。
引入依赖之后: 第二步: 写AppComponent
package com.chinaCEB.cebActivity.components; import android.content.Context; import com.chinaCEB.cebActivity.App; import com.chinaCEB.cebActivity.modules.AppModule; import javax.inject.Singleton; import dagger.Component; /** * Created by niuxiaowei on 16/3/19. */ //AppModule: 这里提供了AppComponent里的需要注入的对象。 @Singleton @Component(modules={AppModule.class}) //AppComponent: 生命周期跟Application一样的组件。可注入到自定义的Application类中,@Singletion代表各个注入对象为单例。 public interface AppComponent { Context getContext(); void inject(App app); // void inject(BaseActivity baseActivity); // Test test(); } 123456789101112131415161718192021222324252627282930 123456789101112131415161718192021222324252627282930只要你按照上面这种方法写的,那么,你的AppComponent 就会被dragger2换一个名字:DaggerAppComponent 。所有的都是。这就是rebuilt的结果。
第三步: 写完了AppComponent,写完了桥,那就该写model了
import android.content.Context; import javax.inject.Singleton; import dagger.Module; import dagger.Provides; /** * Created by niuxiaowei on 16/3/19. */ @Module public class AppModule { Context context; public AppModule(Context context){ this.context = context; } @Provides @Singleton public Context provideContext(){ return context; } // @Provides @Singleton // public Test provideTest(){ // return new Test(); // } } 123456789101112131415161718192021222324252627282930313233 123456789101112131415161718192021222324252627282930313233然后重复activity 的component ,module
package com.chinaCEB.cebActivity.components; import com.chinaCEB.cebActivity.modules.ActivityModule; import com.chinaCEB.cebActivity.scope.PerActivity; import com.chinaCEB.cebActivity.view.LoginActivity; import dagger.Component; /** * * Created by niuxiaowei on 16/3/20. */ //ActivityComponent,可以看到有个@ActivityScope注解,这个注解是自定义的,对应Activity的生命周期,Dagger2可以通过自定义注解限定注解作用域。 //ActivityComponent:生命周期跟Activity一样的组件,这里提供了inject方法将Activity注入到ActivityComponent中,通过该方法,将Activity中需要注入的对象注入到该Activity中。 @PerActivity @Component(dependencies = AppComponent.class,modules = {ActivityModule.class}) public interface ActivityComponent { void inject(LoginActivity loginActivity); // Activity getActivity(); // void inject(LoginActivity loginActivity); } 1234567891011121314151617181920212223 1234567891011121314151617181920212223void inject(LoginActivity loginActivity); 必须要写这个去掉不行
activitymodel
package com.chinaCEB.cebActivity.modules; import android.app.Activity; import com.chinaCEB.cebActivity.scope.PerActivity; import com.chinaCEB.cebActivity.view.ILoginActivity; import com.chinaCEB.cebActivity.view.LoginActivity; import dagger.Module; import dagger.Provides; /** * 提供baseactivity的module * Created by niuxiaowei on 16/3/20. */ //ActivityModule:注入Activity,同时规定Activity所对应的域是@PerActivity @Module public class ActivityModule { private final Activity activity; public ActivityModule(Activity activity){ this.activity = activity; } // @Provides @PerActivity // public Activity provideActivity(){ // return activity; // } @Provides @PerActivity ILoginActivity provideILoginActivity() { return (LoginActivity) this.activity; } } 123456789101112131415161718192021222324252627282930313233343536373839 123456789101112131415161718192021222324252627282930313233343536373839model提供你的对象,也就是你用到的对象,初始化你要的present的时候,或者全局用到的对象
@Provides @PerActivity ILoginActivity provideILoginActivity() { return (LoginActivity) this.activity; } 12345 12345然后在mvp 的p里面:
public class LoginPresenter { private IUserbiz userbiz; private ILoginActivity loginActivity; private int i = -1; @Inject public LoginPresenter(ILoginActivity loginActivity) { this.loginActivity = loginActivity; userbiz=new Userbiz(); } 12345678910 12345678910 inject一下不得不说,dragger2很吊。全局 和局部的对象做的很好。
之后再loginactivity:
@Inject LoginPresenter loginPresenter; initInject(); private void initInject() { // 构建Component并注入 getActivityComponent().inject(this); // loginPresenter.attachView(this); } // 建议写在MyApplication类里 public AppComponent getAppComponent(){ return DaggerAppComponent.builder() .appModule(new AppModule((App)getApplicationContext())) .build(); } // 建议写在基类Activity里 protected ActivityComponent getActivityComponent(){ return DaggerActivityComponent.builder() .appComponent(getAppComponent()) .activityModule(getActivityModule()) .build(); } // 建议写在基类Activity里 protected ActivityModule getActivityModule(){ return new ActivityModule(this); } 1234567891011121314151617181920212223242526272829303132333435363738 1234567891011121314151617181920212223242526272829303132333435363738ok,弄了一天,终于可以运行了。
第一,我不知道DraggerAppComment是动态生成的。很坑。 第二,就是原理理解的不到位,导致不知道怎么写。
总结一个: dragger2 的作用就是依赖注入,并且分model和commpant, 比如okhttp全局一个就行,还有的是页面自己的一些对象,那么就写在自己的modules里面。
说白了就是写两个文件,一个module,一个commpant,而且格式不就是那样的。
顶