我尝试将Dagger2与AppWidgetProvider一起使用。
但是我的豆从未被匕首注入。
我从示例开始:https://github.com/googlesamples/android-architecture-components/tree/master/GithubBrowserSample
我的AppModule:
@Module
public class AppModule {
@Provides
@Singleton
Context providesApplicationContext(Application application) {
return application;
}
@Singleton @Provides
MyDb provideDb(Application app) {
return Room.databaseBuilder(app, MyDb.class,"my.db")
.build();
}
@Provides
@Singleton
SharedPreferences providesSharedPreferences(Application application) {
return PreferenceManager.getDefaultSharedPreferences(application);
}
}
我的天气模块
@Module
public class WeatherModule {
@Singleton @Provides
public OpenWeatherMapService provideOpenWeatherMapService() {
return new Retrofit.Builder()
.baseUrl(BuildConfig.OPEN_WEATHER_MAP_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(new LiveDataCallAdapterFactory())
.build()
.create(OpenWeatherMapService.class);
}
@Singleton @Provides
public WeatherDao provideWeatherDao(MyDb db) {
return db.weatherDao();
}
}
我的Widget Dagger组件:
@Singleton
@Component(modules = {AppModule.class, WeatherModule.class})
public interface WeatherWidgetComponent {
void inject(Context context);
}
我的应用程序:
public class MyApplication extends Application implements HasActivityInjector {
@Inject
DispatchingAndroidInjector<Activity> dispatchingAndroidInjector;
private WeatherWidgetComponent weatherWidgetComponent;
@Override
public void onCreate() {
super.onCreate();
AppInjector.init(this);
weatherWidgetComponent = DaggerWeatherWidgetComponent.builder()
.build();
}
public WeatherWidgetComponent getWeatherWidgetComponent() {
return weatherWidgetComponent;
}
@Override
public DispatchingAndroidInjector<Activity> activityInjector() {
return dispatchingAndroidInjector;
}
}
我的AppWidgetProvider
public class WeatherAppWidgetProvider extends AppWidgetProvider {
@Inject
WeatherDao weatherDao;
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
inject(context);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
inject(context);
for (int widgetId : appWidgetIds) {
updateUI(appWidgetManager, context, widgetId);
}
}
@Override
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) {
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
inject(context);
updateUI(appWidgetManager, context, appWidgetId);
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
inject(context);
}
private void inject(Context context){
Timber.d("inject");
if(weatherDao ==null) {
Timber.d("null so try to inject");
((MyApplication) context.getApplicationContext()).getWeatherWidgetComponent().inject(context);
}
}
private void updateUI(AppWidgetManager appWidgetManager, Context context, int appWidgetId){
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.weather_widget);
if(weatherDao ==null){
Timber.d("weatherDao null");
}
}
}
在logcat中,我总是有:
11-14 18:41:43.494 3812 3812 D WeatherAppWidget提供:注入
11-14 18:41:43.495 3812 3812 D WeatherAppWidgetProvide:null,请尝试注入
11-14 18:41:43.198 3812 3812 D WeatherAppWidget提供:weatherDao空
最佳答案
正如Gabor在评论中指出的那样,您必须为字段注入指定一个具体的类。
@Singleton
@Component(modules = {AppModule.class, WeatherModule.class})
public interface WeatherWidgetComponent {
void inject(Context context);
}
注入
Context
不会执行任何操作,因为Context
没有任何@Inject
带注释的字段。生成的代码基本上将尝试注入上下文并且不执行任何操作。如果将
void inject(Context context)
的调用替换为void inject(WeatherAppWidgetProvider provider)
,则Dagger将生成正确注入WeatherAppWidgetProvider
的代码,而调用.inject(this)
实际上会执行某些操作。