AppWidgetProvider与dagger2

时间:2017-11-14 18:04:19

标签: android android-widget dagger-2

我尝试将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

1 个答案:

答案 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)会实际执行某些操作。