[英]Dagger 2 : error while getting a multiple instances of same object with @Named
How can i get multiple instances of same return type like cursor 我怎么能得到像光标一样的多个相同返回类型的实例
for example :- 例如 :-
Module
@CursorScope
public class CursorModule {
@Provides
Cursor provideSongCursor(
@Named("Song") Musician musician) {
return musician.getApplicationContext().getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{
BaseColumns._ID,
MediaStore.Audio.AudioColumns.TITLE,
MediaStore.Audio.AudioColumns.ARTIST,
MediaStore.Audio.AudioColumns.ALBUM,
MediaStore.Audio.AudioColumns.DURATION
}, MediaStore.Audio.AudioColumns.IS_MUSIC + "=1", null, null);
}
@Provides
Cursor provideAlbumCursor(
@Named("Album") Musician musician) {
return musician.getApplicationContext().getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
new String[]{
BaseColumns._ID,
MediaStore.Audio.AlbumColumns.ALBUM,
MediaStore.Audio.AlbumColumns.ARTIST,
MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS,
MediaStore.Audio.AlbumColumns.FIRST_YEAR
}, null, null, null);
}
@Provides
Cursor provideArtistCursor(@Named("Artist") Musician musician) {
return musician.getApplicationContext().getContentResolver().query(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
new String[] {
BaseColumns._ID,
MediaStore.Audio.ArtistColumns.ARTIST,
MediaStore.Audio.ArtistColumns.NUMBER_OF_ALBUMS,
MediaStore.Audio.ArtistColumns.NUMBER_OF_TRACKS
}, null, null,null);
}
@Provides
Cursor provideGenreCursor(
@Named("Genres") Musician musician) {
return musician.getApplicationContext().getContentResolver().query(MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI,
new String[] {
BaseColumns._ID,
MediaStore.Audio.GenresColumns.NAME
}, null, null, null);
}
@Provides
Cursor providePlaylistCursor(@Named("Playlist") Musician musician) {
return musician.getApplicationContext().getContentResolver().query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
new String[] {
BaseColumns._ID,
MediaStore.Audio.PlaylistsColumns.NAME
}, null, null, null);
}
}
which is provided in 提供的
@CursorScope
@Subcomponent(modules = CursorModule.class)
public interface CursorComponent {
Cursor cursor();
}
I get this error 我收到这个错误
Error:(17, 11) Gradle: error: android.database.Cursor is bound multiple times:
@Provides android.database.Cursor com.merkmod.musician.dependency.CursorModule.provideSongCursor(@Named("Song") com.merkmod.musician.application.Musician)
@Provides android.database.Cursor com.merkmod.musician.dependency.CursorModule.provideAlbumCursor(@Named("Album") com.merkmod.musician.application.Musician)
@Provides android.database.Cursor com.merkmod.musician.dependency.CursorModule.provideArtistCursor(@Named("Artist") com.merkmod.musician.application.Musician)
@Provides android.database.Cursor com.merkmod.musician.dependency.CursorModule.provideGenreCursor(@Named("Genres") com.merkmod.musician.application.Musician)
@Provides android.database.Cursor com.merkmod.musician.dependency.CursorModule.providePlaylistCursor(@Named("Playlist") com.merkmod.musician.application.Musician)
I made multiple instances of Cursor and annotated with @Named at provider level first then it started giving me error with cannot be provided with @Provides annotation so i shifted to using it inside the constructor 我创建了多个Cursor实例,并在提供程序级别使用@Named进行注释,然后它开始给我错误,无法提供@Provides注释,所以我转而在构造函数中使用它
like in the code above . 就像上面的代码一样。 The problem is running a cycle again and again and i am like stuck in getting the cursor stuff done , any help will be appreaciated. 问题是一次又一次地运行一个循环,我就像陷入完成光标的工作一样,任何帮助都会得到应用。
when you want to provide multiple variable of one type you must use @Named
annotation like below: 当你想提供一种类型的多个变量时,你必须使用如下所示的@Named
注释:
Module
@CursorScope
public class CursorModule {
@Provides
@Named("songCursor")
Cursor provideSongCursor(
@Named("Song") Musician musician) {
return musician.getApplicationContext().getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[]{
BaseColumns._ID,
MediaStore.Audio.AudioColumns.TITLE,
MediaStore.Audio.AudioColumns.ARTIST,
MediaStore.Audio.AudioColumns.ALBUM,
MediaStore.Audio.AudioColumns.DURATION
}, MediaStore.Audio.AudioColumns.IS_MUSIC + "=1", null, null);
}
@Provides
@Named("albumCursor")
Cursor provideAlbumCursor(
@Named("Album") Musician musician) {
return musician.getApplicationContext().getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
new String[]{
BaseColumns._ID,
MediaStore.Audio.AlbumColumns.ALBUM,
MediaStore.Audio.AlbumColumns.ARTIST,
MediaStore.Audio.AlbumColumns.NUMBER_OF_SONGS,
MediaStore.Audio.AlbumColumns.FIRST_YEAR
}, null, null, null);
}
@Provides
@Named("artistCursor")
Cursor provideArtistCursor(@Named("Artist") Musician musician) {
return musician.getApplicationContext().getContentResolver().query(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
new String[] {
BaseColumns._ID,
MediaStore.Audio.ArtistColumns.ARTIST,
MediaStore.Audio.ArtistColumns.NUMBER_OF_ALBUMS,
MediaStore.Audio.ArtistColumns.NUMBER_OF_TRACKS
}, null, null,null);
}
@Provides
@Named("genreCursor")
Cursor provideGenreCursor(
@Named("Genres") Musician musician) {
return musician.getApplicationContext().getContentResolver().query(MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI,
new String[] {
BaseColumns._ID,
MediaStore.Audio.GenresColumns.NAME
}, null, null, null);
}
@Provides
@Named("playListCursor")
Cursor providePlaylistCursor(@Named("Playlist") Musician musician) {
return musician.getApplicationContext().getContentResolver().query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
new String[] {
BaseColumns._ID,
MediaStore.Audio.PlaylistsColumns.NAME
}, null, null, null);
}
}
then when you want to inject write like below: 那么当你想要像下面这样注入时:
@Inject
@Named("soundCursor")
Cursor soundCursor;
@Inject
@Named("albumCursor")
Cursor albumCursor;
@Inject
@Named("artistCursor")
Cursor artistCursor;
@Inject
@Named("genreCursor")
Cursor genreCursor;
@Inject
@Named("playListCursor")
Cursor playListCursor;
if you wan to inject them in constructor injections do like below: 如果你想在构造函数注射中注射它们,请执行以下操作:
@Inject
public SomeClassConstructor(@Named("album") Cursor cursur)
and what you have written in your subcomponent interface I cant get it what it is, it must be like: 以及你在你的子组件界面中写的东西我不能得到它是什么,它必须像:
@CursorScope
@Subcomponent(modules = CursorModule.class)
public interface CursorComponent {
void inject(TheClassThatWantsToUseInject1 obj);
void inject(TheClassThatWantsToUseInject2 obj);
}
and in your application component: 在您的应用程序组件中:
YourSubComponentInterface plus(CursorModule module);
so finally I got the answer to my own question and it was the component part itself , you know software development is a so much of a hectic that too it becomes more of a burden when you quit cigerrates. 所以最后我得到了我自己的问题的答案,它是组件本身,你知道软件开发是如此繁忙,当你退出cigerrates时它也变得更加负担。
so all of the above was a simple approach and i made a different example with sharepreference, because my lappy crashed on archlinux. 所以上面所有的都是一个简单的方法,我用sharepreference做了一个不同的例子,因为我的lappy在archlinux上崩溃了。
so here are the snippet of the code i produced. 所以这里是我生成的代码片段。
so the only thing i should have done is that i should have removed cursor injection params from the component interface. 所以我唯一应该做的就是我应该从组件接口中删除游标注入参数。
none the less the snippet might help people. 然而,片段可能会帮助人们。
Component :- 零件 :-
@Singleton
@Component(modules = {MusicianModule.class, SharedPreferencesModule.class})
public interface MusicianComponent {
void inject(MainActivity mainActivity);
Musician musician();
}
Module :- 模块: -
@Module
public class SharedPreferencesModule {
@Provides
@Named("default")
SharedPreferences provideDefaultsharedPreferences(Musician musician) {
return musician.getSharedPreferences("default", Context.MODE_PRIVATE);
}
@Provides
@Named("secret")
SharedPreferences provideSecretsharedPreferences(Musician musician) {
return musician.getSharedPreferences("secret", Context.MODE_PRIVATE);
}
}
Musician Module :- 音乐家模块: -
@Module
public class MusicianModule {
private Musician musician;
public MusicianModule(Musician musician) {
this.musician = musician;
}
@Provides @Singleton
Musician providemusician() {
return musician;
}
@Provides @Singleton
Application provideapplication(Musician musician) {
return musician;
}
}
Application class :- 申请类: -
public class Musician extends Application {
private MusicianComponent musicianComponent;
@Override
public void onCreate() {
resolvedependency();
super.onCreate();
}
private void resolvedependency() {
musicianComponent = DaggerMusicianComponent.builder()
.musicianModule(new MusicianModule(this))
.sharedPreferencesModule(new SharedPreferencesModule())
.build();
}
public static MusicianComponent getMusicianComponent(Context context) {
return ((Musician)context.getApplicationContext()).musicianComponent;
}
}
And the injection in the MainActivity :- 并且MainActivity注入: -
public class MainActivity extends AppCompatActivity {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
@Inject @Named("default")
SharedPreferences defSharedPreferences;
@Inject @Named("secret")
SharedPreferences secSharedPreferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Musician.getMusicianComponent(this).inject(this);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
defSharedPreferences.edit().putString("status", "worked").apply();
secSharedPreferences.edit().putString("status", "worked").apply();
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_song, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
return PlaceholderFragment.newInstance(position + 1);
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "SECTION 1";
case 1:
return "SECTION 2";
case 2:
return "SECTION 3";
}
return null;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.