MVVM Dagger2 组件中存在具有匹配键的绑定
MVVM Dagger2 A Binding With Matching Key Exists in Component
我正在使用以下 google 示例项目:https://github.com/googlesamples/android-architecture-components 作为我的新项目的参考,但在尝试向该项目添加第二个 activity 时遇到困难。
这是我在编译时得到的错误
Error:(22, 8) error: [dagger.android.AndroidInjector.inject(T)] com.apps.myapp.ui.common.MainActivity cannot be provided without an @Inject constructor or from an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.
com.apps.myapp.ui.common.MainActivity is injected at
com.apps.myapp.ui.common.NavigationController.<init>(mainActivity)
com.apps.myapp.ui.common.NavigationController is injected at
com.apps.myapp.ui.addContacts.AddContactsFragment.navigationController
com.apps.myapp.ui.addContacts.AddContactsFragment is injected at
dagger.android.AndroidInjector.inject(arg0)
A binding with matching key exists in component: com.apps.myapp.di.ActivityModule_ContributeMainActivity.MainActivitySubcomponent
这是我的代码
活动模块
@Module
public abstract class ActivityModule {
@ContributesAndroidInjector(modules = FragmentBuildersModule.class)
abstract MainActivity contributeMainActivity();
@ContributesAndroidInjector(modules = FragmentBuildersModule.class)
abstract ContactActivity contributeContactActivity();
}
应用组件
@Singleton
@Component(modules = {
AndroidInjectionModule.class,
AppModule.class,
ActivityModule.class})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance Builder application(Application application);
AppComponent build();
}
void inject(App app);
}
AppInjector
public class AppInjector {
private AppInjector() {}
public static void init(App app) {DaggerAppComponent.builder().application(app).build().inject(app);
app.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
handleActivity(activity);
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
});
}
private static void handleActivity(Activity activity) {
if (activity instanceof HasSupportFragmentInjector) {
AndroidInjection.inject(activity);
}
if (activity instanceof FragmentActivity) {
((FragmentActivity) activity).getSupportFragmentManager()
.registerFragmentLifecycleCallbacks(
new FragmentManager.FragmentLifecycleCallbacks() {
@Override
public void onFragmentCreated(FragmentManager fm, Fragment f,
Bundle savedInstanceState) {
if (f instanceof Injectable) {
AndroidSupportInjection.inject(f);
}
}
}, true);
}
}
}
AppModule
@Module(includes = ViewModelModule.class)
class AppModule {
@Singleton @Provides
BnderAPIService provideService() {
return new Retrofit.Builder()
.baseUrl("serverurl")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(new LiveDataCallAdapterFactory())
.build()
.create(APIService.class);
}
@Singleton @Provides
Db provideDb(Application app) {
return Room.databaseBuilder(app, Db.class,"Db.db").build();
}
@Singleton @Provides
UserDao provideUserDao(Db db) {
return db.userDao();
}
@Singleton @Provides
ContactDao provideContactDao(Db db) {
return db.contactDao();
}
}
FragmentBuildersModule
@Module
public abstract class FragmentBuildersModule {
@ContributesAndroidInjector
abstract AddContactsFragment contributeAddUserFragment();
@ContributesAndroidInjector
abstract ContactsFragment contributeContactsFragment();
@ContributesAndroidInjector
abstract ChalkboardFragment contributeChalkboardFragment();
}
可注射
public interface Injectable {
}
ViewModelKey
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@MapKey
@interface ViewModelKey {
Class<? extends ViewModel> value();
}
ViewModelModule
@Module
abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(AddContactsViewModel.class)
abstract ViewModel bindAddContactsViewModel(AddContactsViewModel addContactsViewModel);
@Binds
@IntoMap
@ViewModelKey(ContactsViewModel.class)
abstract ViewModel bindContactsViewModel(ContactsViewModel contactsViewModel);
@Binds
@IntoMap
@ViewModelKey(ChalkboardViewModel.class)
abstract ViewModel bindChalkboardViewModel(ChalkboardViewModel chalkboardViewModel);
@Binds
abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelFactory factory);
}
申请
public class App extends Application implements HasActivityInjector {
@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
}
AppInjector.init(this);
}
@Override
public DispatchingAndroidInjector<Activity> activityInjector() {
return dispatchingAndroidInjector;
}
}
导航控制器
public class NavigationController {
private final int containerId;
private final FragmentManager fragmentManager;
@Inject
public NavigationController(MainActivity mainActivity) {
this.containerId = R.id.container;
this.fragmentManager = mainActivity.getSupportFragmentManager();
}
public void navigateToUsers() {
Log.i("TAG", "Navigate to users");
String tag = "users";
AddContactsFragment userFragment = AddContactsFragment.create();
fragmentManager.beginTransaction()
.replace(containerId, userFragment, tag)
.addToBackStack(null)
.commitAllowingStateLoss();
}
public void navigateToContacts() {
Log.i("TAG", "Navigate to contacts");
String tag = "contacts";
ContactsFragment contactsFragment = ContactsFragment.create();
fragmentManager.beginTransaction()
.add(contactsFragment, tag)
.addToBackStack(null)
.commitAllowingStateLoss();
}
public void navigateToChalkboard() {
Log.i("TAG", "Navigate to chalkboard");
String tag = "chalkboard";
ChalkboardFragment chalkboardFragment = ChalkboardFragment.create();
fragmentManager.beginTransaction()
.add(chalkboardFragment, tag)
.addToBackStack(null)
.commitAllowingStateLoss();
}
}
主要活动
public class MainActivity extends AppCompatActivity implements LifecycleRegistryOwner, HasSupportFragmentInjector {
private final LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
@Inject
DispatchingAndroidInjector<Fragment> dispatchingAndroidInjector;
@Inject
NavigationController navigationController;
private Toolbar toolbar;
@Override
public LifecycleRegistry getLifecycle() {
return lifecycleRegistry;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setHandler(this);
binding.setManager(getSupportFragmentManager());
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
@Override
public DispatchingAndroidInjector<Fragment> supportFragmentInjector() {
return dispatchingAndroidInjector;
}
static class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
@BindingAdapter({"handler"})
public static void bindViewPagerAdapter(final ViewPager view, final MainActivity activity) {
final ViewPagerAdapter adapter = new ViewPagerAdapter(activity.getSupportFragmentManager());
adapter.addFragment(new ChalkboardFragment(), "Chalkboard");
adapter.addFragment(new ContactsFragment(), "Contacts");
view.setAdapter(adapter);
}
@BindingAdapter({"pager"})
public static void bindViewPagerTabs(final TabLayout view, final ViewPager pagerView) {
view.setupWithViewPager(pagerView, true);
}
}
联系活动
public class ContactActivity extends AppCompatActivity implements LifecycleRegistryOwner, HasSupportFragmentInjector {
private final LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
@Inject
DispatchingAndroidInjector<Fragment> dispatchingAndroidInjector;
@Override
public LifecycleRegistry getLifecycle() {
return lifecycleRegistry;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact);
if (savedInstanceState == null) {
}
}
@Override
public DispatchingAndroidInjector<Fragment> supportFragmentInjector() {
return dispatchingAndroidInjector;
}
}
"A binding with matching key exists in component" 表示您在整个对象图中的某处绑定了一个依赖项,但无法从需要注入它的子组件到达它。这是 javadoc:
Utility code that looks for bindings matching a key in all subcomponents in a binding graph so that a user is advised that a binding exists elsewhere when it is not found in the current subgraph. If a binding matching a key exists in a sub- or sibling component, that is often what the user actually wants to use.
例如,假设您有两个活动,ActivityA 和 ActivityB。您使用 @ContributesAndroidInjector
生成子组件并在 ActivityA 模块中绑定 Foo
而不是 ActivityB 模块。如果您请求使用 @Inject Foo foo
在 ActivityB 中注入 Foo
,您将收到该错误消息。
在您的特定情况下,您遇到的错误可以通过以下方式重现:
正在从 GitHub
克隆项目
git clone https://github.com/googlesamples/android-architecture-components.git`
复制粘贴 MainActivity
到一个新文件中 ContactsActivity
修改 MainActivityModule
使其看起来像您的 ActivityModule
所以由此我们可以断定你的ActivityModule
是有问题的。 @ContributesAndroidInjector
并不像看起来那么简单。这实际上意味着您正在为您在此处指定的 Activity 创建一个新的 Dagger 2 子组件(请参阅 docs here)。
子组件可以使用父组件的绑定,但不能使用同级组件。 ActivityModule
中 ContributesAndroidInjector
的两行创建两个同级子组件:一个用于 MainActivity
和一个用于 ContactsActivity
.
但是,NavigationController
依赖于 MainActivity
,它在 MainActivity
子组件的对象图中绑定,但在 ContactsActivity
子组件的对象图中不绑定。 AddContactsFragment
已成为 ContactsActivity
子组件对象图的一部分,并且无法再访问 MainActivity
。这意味着当 Dagger 2 试图在你的 AddContactsFragment
中注入 NavigationController
时,它无法提供 MainActivity
作为它的依赖项。这解释了错误消息的 "cannot provide" 部分。
虽然它不能在那个特定的对象图中提供 MainActivity
,但是 AndroidInjector
大体上知道 MainActivity
因此错误消息 "a binding key exists"。这是什么绑定密钥?将 MainActivity.class
绑定到 MainActivityFactory
的键。这个键绑定在哪里?在 ActivityModule
中,当您为 MainActivity
编写 @ContributesAndroidInjector
时。
如何解决这个问题超出了 Whosebug 问题的范围,因为它涉及冗长的代码重构。您需要重新组织对象图,以便 NavigationController
不再依赖于 MainActivity
。也许你可以让它依赖于 AppCompatActivity
,因为它是你两个活动的超类。然后您将需要停止使用 ContributesAndroidInjector
并为您的两个 Activity 编写显式模块,其中包括 AppCompatActivity
.
的绑定
但是,现在请回到基础并从更简单的事情开始。在没有完全理解的情况下开始一个复杂的项目,然后只是修改它,希望它能工作,这是灾难的根源。
Codepath Dagger 2 tutorial project更容易理解,会让你熟悉Dagger 2中涉及的基本概念。一旦你熟悉了基本概念并理解了依赖组件和子组件,那么你可以尝试一个更难的例子。祝你好运!
我正在使用以下 google 示例项目:https://github.com/googlesamples/android-architecture-components 作为我的新项目的参考,但在尝试向该项目添加第二个 activity 时遇到困难。
这是我在编译时得到的错误
Error:(22, 8) error: [dagger.android.AndroidInjector.inject(T)] com.apps.myapp.ui.common.MainActivity cannot be provided without an @Inject constructor or from an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.
com.apps.myapp.ui.common.MainActivity is injected at
com.apps.myapp.ui.common.NavigationController.<init>(mainActivity)
com.apps.myapp.ui.common.NavigationController is injected at
com.apps.myapp.ui.addContacts.AddContactsFragment.navigationController
com.apps.myapp.ui.addContacts.AddContactsFragment is injected at
dagger.android.AndroidInjector.inject(arg0)
A binding with matching key exists in component: com.apps.myapp.di.ActivityModule_ContributeMainActivity.MainActivitySubcomponent
这是我的代码
活动模块
@Module
public abstract class ActivityModule {
@ContributesAndroidInjector(modules = FragmentBuildersModule.class)
abstract MainActivity contributeMainActivity();
@ContributesAndroidInjector(modules = FragmentBuildersModule.class)
abstract ContactActivity contributeContactActivity();
}
应用组件
@Singleton
@Component(modules = {
AndroidInjectionModule.class,
AppModule.class,
ActivityModule.class})
public interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance Builder application(Application application);
AppComponent build();
}
void inject(App app);
}
AppInjector
public class AppInjector {
private AppInjector() {}
public static void init(App app) {DaggerAppComponent.builder().application(app).build().inject(app);
app.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
handleActivity(activity);
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
});
}
private static void handleActivity(Activity activity) {
if (activity instanceof HasSupportFragmentInjector) {
AndroidInjection.inject(activity);
}
if (activity instanceof FragmentActivity) {
((FragmentActivity) activity).getSupportFragmentManager()
.registerFragmentLifecycleCallbacks(
new FragmentManager.FragmentLifecycleCallbacks() {
@Override
public void onFragmentCreated(FragmentManager fm, Fragment f,
Bundle savedInstanceState) {
if (f instanceof Injectable) {
AndroidSupportInjection.inject(f);
}
}
}, true);
}
}
}
AppModule
@Module(includes = ViewModelModule.class)
class AppModule {
@Singleton @Provides
BnderAPIService provideService() {
return new Retrofit.Builder()
.baseUrl("serverurl")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(new LiveDataCallAdapterFactory())
.build()
.create(APIService.class);
}
@Singleton @Provides
Db provideDb(Application app) {
return Room.databaseBuilder(app, Db.class,"Db.db").build();
}
@Singleton @Provides
UserDao provideUserDao(Db db) {
return db.userDao();
}
@Singleton @Provides
ContactDao provideContactDao(Db db) {
return db.contactDao();
}
}
FragmentBuildersModule
@Module
public abstract class FragmentBuildersModule {
@ContributesAndroidInjector
abstract AddContactsFragment contributeAddUserFragment();
@ContributesAndroidInjector
abstract ContactsFragment contributeContactsFragment();
@ContributesAndroidInjector
abstract ChalkboardFragment contributeChalkboardFragment();
}
可注射
public interface Injectable {
}
ViewModelKey
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@MapKey
@interface ViewModelKey {
Class<? extends ViewModel> value();
}
ViewModelModule
@Module
abstract class ViewModelModule {
@Binds
@IntoMap
@ViewModelKey(AddContactsViewModel.class)
abstract ViewModel bindAddContactsViewModel(AddContactsViewModel addContactsViewModel);
@Binds
@IntoMap
@ViewModelKey(ContactsViewModel.class)
abstract ViewModel bindContactsViewModel(ContactsViewModel contactsViewModel);
@Binds
@IntoMap
@ViewModelKey(ChalkboardViewModel.class)
abstract ViewModel bindChalkboardViewModel(ChalkboardViewModel chalkboardViewModel);
@Binds
abstract ViewModelProvider.Factory bindViewModelFactory(ViewModelFactory factory);
}
申请
public class App extends Application implements HasActivityInjector {
@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
}
AppInjector.init(this);
}
@Override
public DispatchingAndroidInjector<Activity> activityInjector() {
return dispatchingAndroidInjector;
}
}
导航控制器
public class NavigationController {
private final int containerId;
private final FragmentManager fragmentManager;
@Inject
public NavigationController(MainActivity mainActivity) {
this.containerId = R.id.container;
this.fragmentManager = mainActivity.getSupportFragmentManager();
}
public void navigateToUsers() {
Log.i("TAG", "Navigate to users");
String tag = "users";
AddContactsFragment userFragment = AddContactsFragment.create();
fragmentManager.beginTransaction()
.replace(containerId, userFragment, tag)
.addToBackStack(null)
.commitAllowingStateLoss();
}
public void navigateToContacts() {
Log.i("TAG", "Navigate to contacts");
String tag = "contacts";
ContactsFragment contactsFragment = ContactsFragment.create();
fragmentManager.beginTransaction()
.add(contactsFragment, tag)
.addToBackStack(null)
.commitAllowingStateLoss();
}
public void navigateToChalkboard() {
Log.i("TAG", "Navigate to chalkboard");
String tag = "chalkboard";
ChalkboardFragment chalkboardFragment = ChalkboardFragment.create();
fragmentManager.beginTransaction()
.add(chalkboardFragment, tag)
.addToBackStack(null)
.commitAllowingStateLoss();
}
}
主要活动
public class MainActivity extends AppCompatActivity implements LifecycleRegistryOwner, HasSupportFragmentInjector {
private final LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
@Inject
DispatchingAndroidInjector<Fragment> dispatchingAndroidInjector;
@Inject
NavigationController navigationController;
private Toolbar toolbar;
@Override
public LifecycleRegistry getLifecycle() {
return lifecycleRegistry;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setHandler(this);
binding.setManager(getSupportFragmentManager());
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
@Override
public DispatchingAndroidInjector<Fragment> supportFragmentInjector() {
return dispatchingAndroidInjector;
}
static class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
@BindingAdapter({"handler"})
public static void bindViewPagerAdapter(final ViewPager view, final MainActivity activity) {
final ViewPagerAdapter adapter = new ViewPagerAdapter(activity.getSupportFragmentManager());
adapter.addFragment(new ChalkboardFragment(), "Chalkboard");
adapter.addFragment(new ContactsFragment(), "Contacts");
view.setAdapter(adapter);
}
@BindingAdapter({"pager"})
public static void bindViewPagerTabs(final TabLayout view, final ViewPager pagerView) {
view.setupWithViewPager(pagerView, true);
}
}
联系活动
public class ContactActivity extends AppCompatActivity implements LifecycleRegistryOwner, HasSupportFragmentInjector {
private final LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
@Inject
DispatchingAndroidInjector<Fragment> dispatchingAndroidInjector;
@Override
public LifecycleRegistry getLifecycle() {
return lifecycleRegistry;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact);
if (savedInstanceState == null) {
}
}
@Override
public DispatchingAndroidInjector<Fragment> supportFragmentInjector() {
return dispatchingAndroidInjector;
}
}
"A binding with matching key exists in component" 表示您在整个对象图中的某处绑定了一个依赖项,但无法从需要注入它的子组件到达它。这是 javadoc:
Utility code that looks for bindings matching a key in all subcomponents in a binding graph so that a user is advised that a binding exists elsewhere when it is not found in the current subgraph. If a binding matching a key exists in a sub- or sibling component, that is often what the user actually wants to use.
例如,假设您有两个活动,ActivityA 和 ActivityB。您使用 @ContributesAndroidInjector
生成子组件并在 ActivityA 模块中绑定 Foo
而不是 ActivityB 模块。如果您请求使用 @Inject Foo foo
在 ActivityB 中注入 Foo
,您将收到该错误消息。
在您的特定情况下,您遇到的错误可以通过以下方式重现:
正在从 GitHub
克隆项目git clone https://github.com/googlesamples/android-architecture-components.git`
复制粘贴
MainActivity
到一个新文件中ContactsActivity
修改
MainActivityModule
使其看起来像您的ActivityModule
所以由此我们可以断定你的ActivityModule
是有问题的。 @ContributesAndroidInjector
并不像看起来那么简单。这实际上意味着您正在为您在此处指定的 Activity 创建一个新的 Dagger 2 子组件(请参阅 docs here)。
子组件可以使用父组件的绑定,但不能使用同级组件。 ActivityModule
中 ContributesAndroidInjector
的两行创建两个同级子组件:一个用于 MainActivity
和一个用于 ContactsActivity
.
但是,NavigationController
依赖于 MainActivity
,它在 MainActivity
子组件的对象图中绑定,但在 ContactsActivity
子组件的对象图中不绑定。 AddContactsFragment
已成为 ContactsActivity
子组件对象图的一部分,并且无法再访问 MainActivity
。这意味着当 Dagger 2 试图在你的 AddContactsFragment
中注入 NavigationController
时,它无法提供 MainActivity
作为它的依赖项。这解释了错误消息的 "cannot provide" 部分。
虽然它不能在那个特定的对象图中提供 MainActivity
,但是 AndroidInjector
大体上知道 MainActivity
因此错误消息 "a binding key exists"。这是什么绑定密钥?将 MainActivity.class
绑定到 MainActivityFactory
的键。这个键绑定在哪里?在 ActivityModule
中,当您为 MainActivity
编写 @ContributesAndroidInjector
时。
如何解决这个问题超出了 Whosebug 问题的范围,因为它涉及冗长的代码重构。您需要重新组织对象图,以便 NavigationController
不再依赖于 MainActivity
。也许你可以让它依赖于 AppCompatActivity
,因为它是你两个活动的超类。然后您将需要停止使用 ContributesAndroidInjector
并为您的两个 Activity 编写显式模块,其中包括 AppCompatActivity
.
但是,现在请回到基础并从更简单的事情开始。在没有完全理解的情况下开始一个复杂的项目,然后只是修改它,希望它能工作,这是灾难的根源。
Codepath Dagger 2 tutorial project更容易理解,会让你熟悉Dagger 2中涉及的基本概念。一旦你熟悉了基本概念并理解了依赖组件和子组件,那么你可以尝试一个更难的例子。祝你好运!