Как вводить в 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