我正在开发一个音乐应用程序.我想从LastFM加载艺术家的图像,所以我这样做 1.我创建了一个Artist ImageLoader类,扩展了BaseGlideUrlLoader. 2.在getUrl方法中,我使用retrofit2通过 getArtistInfo方法从La
1.我创建了一个Artist ImageLoader类,扩展了BaseGlideUrlLoader.
2.在getUrl方法中,我使用retrofit2通过 getArtistInfo方法从LastFM获取艺术家的图像URL.
我的问题是我不知道如何注入改造服务以在ArtistImageLoader中发出请求.我这样做但我得到了一个NOP例外. lastFmService没有被注入.
// GlideModule glide.register(MLocalArtist.class, InputStream.class, new ArtistImageLoader.Factory()); // Use it in onCreate method of ArtistsFragment DaggerLastFmComponent.builder().activityModule(new ActivityModule(getActivity())) .netComponent(getNetComponent()) .build().inject(this); // use this code in onBindViewHolder method of artists recycler adapter Glide.with(getContext()) .from(MLocalArtist.class) .load(localArtist) .into(localArtistViewHolder.ivArtwork);
ArtistImageLoader
public class ArtistImageLoader extends BaseGlideUrlLoader<MLocalArtist> { @Inject LastfmService lastfmService; public ArtistImageLoader(Context context) { super(context); } @Override protected String getUrl(MLocalArtist model, int width, int height) { Call<List<MArtist>> call = lastfmService.getArtistInfo(model.artistName); try { List<MArtist> artists = call.execute().body(); if (artists != null && artists.size() > 0) { Timber.e(artists.get(0).toString()); } } catch (IOException e) { e.printStackTrace(); } return null; } public static class Factory implements ModelLoaderFactory<MLocalArtist, InputStream> { @Override public ModelLoader<MLocalArtist, InputStream> build(Context context, GenericLoaderFactory factories) { return new ArtistImageLoader(context); } @Override public void teardown() { } } }
你能帮帮我吗?非常感谢!
滑翔版:3.7.0
集成库:OkHttp3 Dagger2
设备/ Android版本:Android模拟器华硕zenfone 5
编辑1
ActivityComponent.java
@PerActivity @Component(dependencies = AppComponent.class, modules = ActivityModule.class) public interface ActivityComponent { Context context(); }
AppComponent.java
@Singleton @Component(modules = AppModule.class) public interface AppComponent { App app(); }
NetComponent.java
@Singleton @Component(modules = {NetModule.class, AppModule.class}) public interface NetComponent { @Named("chartSoundCloud") Retrofit getSoundcloudChartRetrofit(); @Named("searchSoundCloud") Retrofit getSoundcloudSearchRetrofit(); @Named("lastFM") Retrofit getLastFmRetrofit(); }
LastFmComponent.java
@PerActivity @Component(dependencies = NetComponent.class, modules = {LastFmModule.class, ActivityModule.class}) public interface LastFmComponent extends ActivityComponent { void inject(ArtistsFragment artistsFragment); }
ActivityModule.java
@Module public class ActivityModule { private final Context mContext; public ActivityModule(Context mContext) { this.mContext = mContext; } @Provides @PerActivity Context provideActivityContext() { return mContext; } }
AppModule.java
@Module public class AppModule { private App app; public AppModule(App app){ this.app = app; } @Singleton @Provides App provideApplication() { return app; } @Singleton @Provides @Named("applicationContext") Context provideApplicationContext(){ return app; } }
LastFmModule.java
@Module public class LastFmModule { @Provides @PerActivity LastfmService provideLastFmService(@Named("lastFM") Retrofit retrofit) { return retrofit.create(LastfmService.class); } }
NetModule.java
@Module public class NetModule { static final int DISK_CACHE_SIZE = (int) MEGABYTES.toBytes(50); @Provides @Singleton Cache provideOkHttpCache(@Named("applicationContext") Context application) { Cache cache = new Cache(application.getCacheDir(), DISK_CACHE_SIZE); return cache; } @Provides @Singleton ScdClientIdInterceptor provideScdClientIdInterceptor() { return new ScdClientIdInterceptor(); } @Provides @Singleton LastFMInterceptor provideLastFmInterceptor() { return new LastFMInterceptor(); } @Provides @Singleton HttpLoggingInterceptor provideHttpLoggingInterceptor() { return new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY); } @Provides @Singleton @Named("soundcloud-Http") OkHttpClient provideOkHttpSoundCloudClient(Cache cache, ScdClientIdInterceptor clientIdInterceptor, HttpLoggingInterceptor httpLoggingInterceptor) { return createOkHttpClient(cache, clientIdInterceptor, httpLoggingInterceptor); } @Provides @Singleton @Named("lastFM-Http") OkHttpClient provideOkHttpLastFmClient(Cache cache, LastFMInterceptor clientIdInterceptor, HttpLoggingInterceptor httpLoggingInterceptor) { return createOkHttpClient(cache, clientIdInterceptor, httpLoggingInterceptor); } private OkHttpClient createOkHttpClient(Cache cache, Interceptor clientIdInterceptor, HttpLoggingInterceptor httpLoggingInterceptor) { OkHttpClient okHttpClient = new OkHttpClient.Builder() .cache(cache) .addInterceptor(clientIdInterceptor) .addInterceptor(httpLoggingInterceptor) .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .build(); return okHttpClient; } @Provides @Singleton Gson provideGson() { return GsonFactory.create(); } @Provides @Singleton @Named("searchSoundCloud") Retrofit provideSearchSoundCloudRetrofit(Gson gson, @Named("soundcloud-Http") OkHttpClient okHttpClient) { Retrofit searchRetrofit = new Retrofit.Builder() .baseUrl(Constants.BASE_SOUNDCLOUD_API_URL) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create(gson)) .build(); return searchRetrofit; } @Provides @Singleton @Named("chartSoundCloud") Retrofit provideChartSoundCloudRetrofit(Gson gson, @Named("soundcloud-Http") OkHttpClient okHttpClient) { Retrofit chartRetrofit = new Retrofit.Builder() .baseUrl(Constants.BASE_SOUNDCLOUD_API_V2_URL) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create(gson)) .build(); return chartRetrofit; } @Provides @Singleton @Named("lastFM") Retrofit provideLastFmRetrofit(Gson gson, @Named("lastFM-Http") OkHttpClient okHttpClient) { Retrofit retrofit = new Retrofit.Builder() .baseUrl(Constants.LASTFM_API_URL) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create(gson)) .build(); return retrofit; } }我的假设是你的ArtistImageLoader是在一个单独的类中定义的.你的问题的原因是匕首的工作方式.它只会在您指定为注入方法参数的类上注入使用@Inject注释的字段.因此,注入@Inject的ArtistImageLoader内部不会注入任何内容,只会注入在ArtistsFragment中定义的带注释字段.
我建议在片段中使用@Inject注释定义LastfmService字段,并将实例传递给Glide LoaderFactory.工厂可以将其提供给装载机的实例.它不是最好的解决方案,但由于您无法直接将其传递给实例,因此这似乎是可行的解决方法.
另一种方法是在自定义应用程序中构建依赖关系树.这允许您从任何地方访问依赖项,而不依赖于活动生命周期.