我尝试将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);
}
}
My WeatherModule
@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();
}
}
My 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 null
答案 0 :(得分:1)
正如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)
会实际执行某些操作。