Как вводить в BroadcastReceiver

Кто-то уже должен был ввести уже существующий класс с некоторой бизнес-логикой в ​​BroadcastReceiver, используя кинжал?

Я использую кинжал 1 и уже нашел хороший пример (https://github.com/adennie/fb-android-dagger), но я не мог найти, как мы можем добавить уже существующий класс, принадлежащий другому модулю, в BroadcastReceiver.

Приветствуется любая помощь или совет.

Ответ 1

Мне удалось ввести примеры использования в мою трансляцию, определив модуль, который предоставит мне необходимые варианты использования, и я добавлю модуль в метод onReceive, проверьте код ниже:

Мой BroadcastReceiverModule:

@Module(injects = { MyBroadcastReceiver.class }, addsTo = MyAppModule.class)
public class BroadcastReceiverModule {
    @Provides @Singleton MyUtilsClass providesMyUtilsClass(MyUtilsClassImpl myUtilsClass) {
        return myUtilsClass;
    }
    @Provides @Singleton MyUseCase providesMyUseCase(MyUseCaseImpl myUseCaseUtils) {
        return myUseCaseUtils;
    }
}

Мой BroadCastReceiver:

@Inject MyUtilsClass myUtilsClass;
@Inject MyUseCase myUseCase;
@Override public void onReceive(Context context, Intent intent) {
    AcidApplication.getScopedGraph(getModules().toArray()).inject(this);
    myUseCase.call();
    myUtilsClass.doSomething();
}
protected List<Object> getModules() {
    List<Object> result = new ArrayList<>();
    result.add(new BroadcastReceiverModule());
    return result;
}

Ответ 2

То же, что вы введете в Activity

public void onReceive(Context context, Intent intent) {
        ((Application) context.getApplicationContext()).getInjector().inject(this);
    }

Ответ 3

Возможно, будет слишком поздно, чтобы ответить на этот вопрос, но я AppWidgetProvider пример из моего недавнего проекта, в котором я попытался внедрить AppWidgetProvider который является прямым подклассом BroadcastReceiver.

Нам нужно внедрить модифицированный сервис в BroadcastReceiver:

@Module
public class NetModule {
    /** shrunk for simplicity sake. **/
    @Singleton
    @Provides
    public WidgetService provideWidgetService(Application application, OkHttpClient client, Gson gson) {
        return new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create(gson))
                .baseUrl(application.getString(R.string.api_url))
                .client(client)
                .build()
                .create(WidgetService.class);
    }
}

Создайте еще один абстрактный @Module для методов with abstract, аннотированных @ContributesAndroidInjector которые возвращают BroadcastReceiver вы хотите @ContributesAndroidInjector:

/**
 * To inject the app widgets.
 */
@Module
public abstract class WidgetsModule {
    @ContributesAndroidInjector
    abstract IngredientsWidget contributesIngredientsWidget();
}

Если вы забыли добавить этот модуль, вы получите сообщение об ошибке:

java.lang.IllegalArgumentException: фабрика инжектора не привязана к классу <>

Затем компонент с обоими модулями, кроме AndroidInjectionModule

@Singleton
@Component(modules = {AndroidInjectionModule.class, NetModule.class, WidgetsModule.class})
public interface AppComponent {
    void inject(RecipesApp recipesApp);
}

Затем в своем классе Application вы реализуете интерфейс HasBroadcastReceiverInjector.

public class RecipesApp extends Application implements HasBroadcastReceiverInjector {

    @Inject
    DispatchingAndroidInjector<BroadcastReceiver> broadcastReceiverInjector;

    @Override
    public void onCreate() {
        super.onCreate();

        component().inject(this);
    }

    public AppComponent component() {
        return DaggerAppComponent.builder()
                .build();
    }

    @Override
    public AndroidInjector<BroadcastReceiver> broadcastReceiverInjector() {
        return broadcastReceiverInjector;
    }
}

Наконец, вы можете добавить свой BroadcastReceiver внутрь onReceive() перед вызовом super().

public class IngredientsWidget extends AppWidgetProvider {

    @Inject
    public WidgetService api;


    @Override
    public void onReceive(Context context, Intent intent) {
        /** Don't forget this line **/
        AndroidInjection.inject(this, context);
        super.onReceive(context, intent);
    }

}

Вы можете узнать больше о том, как внедрить документы по компонентам Android.

Я построил небольшой образец: трансляция-инъекция.

Ответ 4

Пример Dagger 2 для внедрения объектов в BroadcastReceiver.

BroadcastReceiverModule.kt

@Module
abstract class BroadcastReceiverModule {
    @ContributesAndroidInjector
    abstract fun contributesMyTestReceiver() : MyTestReceiver
}

AppComponent.kt

@Singleton
@Component(
        modules = [
            (AndroidSupportInjectionModule::class),
            (BroadcastReceiverModule::class)
        ])
interface AppComponent : AndroidInjector<MyApp> {
    @Component.Builder
    abstract class Builder : AndroidInjector.Builder<MyApp>()
}

Класс приложения

class MyApp : DaggerApplication() {
    override fun applicationInjector(): AndroidInjector<MyApp> =
            DaggerAppComponent.builder().create([email protected])
}

Класс BroadcastReceiver

class MyTestReceiver : BroadcastReceiver() {

    @Inject
    lateinit var anInjectedObject: MyInjectObject

    override fun onReceive(context: Context, intent: Intent) {
        AndroidInjection.inject(this, context)
        anInjectedObject.doSomthing()
    }
}

Ответ 5

@s-hunter Спасибо, мужик, это действительно помогло мне.

Ответ 6

Вы можете использовать DaggerBroadcastReceiver или переопределить метод onReceive, как показано ниже:

public void onReceive(Context context, Intent intent) {
    AndroidInjection.inject(this, context);
    // your code should be here ...
}

документы кинжала:https://dagger.dev/api/2.24/dagger/android/DaggerBroadcastReceiver