我尝试将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)实际上会执行某些操作。

09-11 18:13