Java 匕首2:获取具有@Named的同一对象的多个实例时出错
我怎样才能像游标一样获得相同返回类型的多个实例 例如:-Java 匕首2:获取具有@Named的同一对象的多个实例时出错,java,android,dependency-injection,dagger,Java,Android,Dependency Injection,Dagger,我怎样才能像游标一样获得相同返回类型的多个实例 例如:- Module @CursorScope public class CursorModule { @Provides Cursor provideSongCursor( @Named("Song") Musician musician) { return musician.getApplicationContext().getContentResolver().query(Medi
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);
}
}
这在中提供
@CursorScope
@Subcomponent(modules = CursorModule.class)
public interface CursorComponent {
Cursor cursor();
}
我得到这个错误
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)
我创建了游标的多个实例,首先在提供程序级别用@Named注释,然后它开始给我错误,因为不能用@Provides注释提供,所以我转而在构造函数内部使用它
就像上面的代码一样。问题是一次又一次地运行一个循环,我好像被困在完成光标的工作中,任何帮助都会得到通知。当您想提供一种类型的多个变量时,您必须使用
@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);
}
}
@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;
@Inject
public SomeClassConstructor(@Named("album") Cursor cursur)
然后,当您要注入时,请按如下方式编写:
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);
}
}
@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;
@Inject
public SomeClassConstructor(@Named("album") Cursor cursur)
如果要在构造函数注入中注入它们,请执行以下操作:
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);
}
}
@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;
@Inject
public SomeClassConstructor(@Named("album") Cursor cursur)
您在子组件界面中所写的内容我无法理解它是什么,它必须是这样的:
@CursorScope
@Subcomponent(modules = CursorModule.class)
public interface CursorComponent {
void inject(TheClassThatWantsToUseInject1 obj);
void inject(TheClassThatWantsToUseInject2 obj);
}
在应用程序组件中:
YourSubComponentInterface plus(CursorModule module);
所以最后我得到了我自己问题的答案,这是组件本身,你知道软件开发是一个非常繁忙的过程,当你退出cigerrates时,它也会成为一个更大的负担 所以以上所有的都是一个简单的方法,我用sharepreference做了一个不同的例子,因为我的lappy在archlinux上崩溃了 下面是我生成的代码片段 因此,我应该做的唯一一件事是,我应该从组件接口中删除游标注入参数 尽管如此,这个片段可能会帮助人们 组成部分:-
@Singleton
@Component(modules = {MusicianModule.class, SharedPreferencesModule.class})
public interface MusicianComponent {
void inject(MainActivity mainActivity);
Musician musician();
}
模块:-
@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);
}
}
@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;
}
}
音乐家模块:-
@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);
}
}
@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;
}
}
申请类别:-
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;
}
}
以及主活动中的注射:-
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;
}
}
组件类错误中仍然存在问题:(17,11)Gradle:error:android.database.Cursor如果没有@Provides注释方法,则无法提供。android.database.Cursor在com.merkmod.music.dependency.CursorComponent.Cursor()上提供。我也知道注入部分。在所有的
游标注入之前,必须先输入@Named
。如果没有@Named
,您将无法再进行任何光标
注入。搜索您的游标注入并更改所有注入,添加一个名为
@的很抱歉,如果没有,如果您有一个工作示例,或者向我显示您请求游标的组件类,我知道依赖项注入图是如何工作的,但我不确定游标是否与@Named兼容。