本篇是實戰文章,從代碼的角度分析這兩種方式。本文參考自下列文章:app
http://www.jianshu.com/p/1d42d2e6f4a5ide
http://www.jianshu.com/p/94d47da32656ui
通常在項目中咱們須要全局使用app或者其餘,這個時候就須要有一個全局的Component做爲橋樑,提供給使用方使用。一個Component能夠依賴一個或多個Component,並拿到被依賴Component 暴露 出來的實例。this
<一>依賴關係spa
全局提供App實例類、上下文Contextcode
@Module public class AppModule5 { private App5 app; public AppModule5(App5 app) { this.app = app; } @Provides public App5 provideApp() { return app; } @Provides Context provideApplicationContext() { return app.getApplicationContext(); } }
提供 全局提供App實例類、上下文Context橋樑,該Component會被其餘Component依賴component
@Component(modules = {AppModule5.class}) public interface AppComponent5 { void inject(App5 app); //由於AppComponent會被dependencies,因此此處Module中提供的內容,咱們須要在此處聲明一下 App5 getApp(); Context getApplicationContext(); }
因爲AppComponent5會被其餘Component依賴,因此此處須要顯示地聲明AppModule5中提供的東西,此處的方法名任意!!!blog
App被全局提供ci
public class App5 extends Application { private AppComponent5 mAppComponent5; @Override public void onCreate() { super.onCreate(); mAppComponent5 = DaggerAppComponent5.builder().appModule5(new AppModule5(this)).build(); mAppComponent5.inject(this); } public AppComponent5 getAppComponent5(){ return mAppComponent5; } }
若Module的構造器須要參數,咱們就須要在這裏appModule5(new AppModule5()),若Module的構造器中不須要參數,此處能夠省略!!!須要經過這種方式將參數傳遞進去。get
提供被依賴類:
@Module public class ActivityModule5 { @Provides public DependencyPresenter getDependencyPresenter(App5 app){ return new DependencyPresenter(app); } }
橋樑:
@Component(dependencies = AppComponent5.class,modules = ActivityModule5.class) public interface ActivityComponent { void inject(TargetActivity5 activity5); }
使用了Component的dependencies屬性,ActivityModule5提供被依賴類,AppComponent5提供被依賴類的參數(全局提供)。
被依賴類:此處沒用@inject修飾構造器
public class DependencyPresenter { public DependencyPresenter(App5 app){ Log.d("Dagger.class","DependencyPresenter-----構造器------(app == null)?????:"+(app == null)); } public void printMethod(){ Log.d("Dagger.class","DependencyPresenter-----printMethod()-----"); } }
目標類
public class TargetActivity5 extends AppCompatActivity { @Inject DependencyPresenter mDependencyPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); App5 app5 = (App5) this.getApplication(); DaggerActivityComponent.builder().appComponent5(app5.getAppComponent5()).build().inject(this); mDependencyPresenter.printMethod(); } }
因爲ActivityComponent依賴AppComponent,因此須要在此處添加聲明appComponent(app5.getAppComponent)。
由此獲得結論:須要在Component中顯示的聲明提供 被依賴類 的方法(方法名任意)
1 同一個Component的兩個Module之間,當ModuleA須要ModuleB提供參數,在Component中須要提供獲取參數的方法
2 ComponentA和它所依賴的ComponentB之間,若ComponentA須要ComponentB提供參數,在ComponentB中須要顯示聲明方法
<二>包含方式(從屬方式)@SubComponent
當咱們的Component須要依賴全局的Component提供的實例或者參數的時候,咱們上面的實現方式是選擇Component的dependencies屬性,此時須要在被依賴的Component中有顯示的聲明。這裏介紹另外一種方法,包含方式。相比於依賴方式,包含方式不須要在父Component中顯示的提供方法,就能夠拿到想要的東西。下面看一下代碼:
使用@Subcomponent註解標註ActivityModule6,表明它是子Component
@Subcomponent(modules = ActivityModule6.class) public interface ActivityComponent6 { void inject(TargetActivity6 activity5); }
父Component:
@Component(modules = {AppModule6.class}) public interface AppComponent6 { void inject(App6 app); ActivityComponent6 getSubComponent(); }
須要在父Component中聲明本身的子Component,方法名任意。若是ActivityComponent6中的Module的構造器須要參數,則在此處傳遞進去,譬如:
ActivityComponent6 getSubComponent(new ActivityModule6("參數"));
目標類:使用方式上也有區別
public class TargetActivity6 extends AppCompatActivity { @Inject DependencyPresenter6 mDependencyPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); App6 app6 = (App6) this.getApplication(); app6.getAppComponent6().getSubComponent().inject(this); mDependencyPresenter.printMethod(); } }
其餘類均沒有變化。依賴方式、包含方式介紹到此爲止~更多的內容請參看上面的連接!!!