Quelqu'un a-t-il déjà dû injecter une classe déjà existante, avec une logique métier, dans un BroadcastReceiver à l'aide d'un poignard?
J'utilise la dague 1 et j'ai déjà trouvé un bel exemple ( https://github.com/adennie/fb-Android-dagger ) mais je n'ai pas trouvé comment ajouter une classe déjà existante , qui appartient à un module différent, dans un BroadcastReceiver.
Toute aide ou conseil serait grandement apprécié.
J'ai réussi à injecter des cas d'utilisation dans ma diffusion en définissant un module qui fournit les cas d'utilisation dont j'ai besoin et j'ajoute le module sur la méthode onReceive, vérifiez le code ci-dessous:
Mon 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;
}
}
Mon 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;
}
Identique à l'injection dans une activité
public void onReceive(Context context, Intent intent) {
((Application) context.getApplicationContext()).getInjector().inject(this);
}
Il est peut-être trop tard pour répondre à cette question, mais je fournirai un exemple de mon récent projet où j'ai essayé d'injecter AppWidgetProvider
qui est une sous-classe directe de BroadcastReceiver
.
Nous devons injecter un service de mise à niveau dans un BroadcastReceiver
:
@Module
public class NetModule {
/** shrunk for simplicity's 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);
}
}
Créez un autre résumé @Module
pour les méthodes abstraites annotées de @ContributesAndroidInjector
qui renvoient BroadcastReceiver
s que vous souhaitez injecter:
/**
* To inject the app widgets.
*/
@Module
public abstract class WidgetsModule {
@ContributesAndroidInjector
abstract IngredientsWidget contributesIngredientsWidget();
}
Si vous avez oublié d'ajouter ce module, vous obtiendrez une erreur comme:
Java.lang.IllegalArgumentException: aucune fabrique d'injecteurs liée pour la classe <>
Ensuite, le composant avec les deux modules, en plus AndroidInjectionModule
@Singleton
@Component(modules = {AndroidInjectionModule.class, NetModule.class, WidgetsModule.class})
public interface AppComponent {
void inject(RecipesApp recipesApp);
}
Ensuite, dans votre classe Application
, vous implémentez l'interface 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;
}
}
Enfin, vous pouvez injecter votre BroadcastReceiver dans onReceive () avant d'appeler le 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);
}
}
Vous pouvez en savoir plus sur la façon d'injecter Android composants docs .
J'ai construit un petit échantillon: diffusion-injection .
Exemple Dagger 2 pour injecter des objets dans un BroadcastReceiver.
Le BroadcastReceiverModule.kt
@Module
abstract class BroadcastReceiverModule {
@ContributesAndroidInjector
abstract fun contributesMyTestReceiver() : MyTestReceiver
}
The AppComponent.kt
@Singleton
@Component(
modules = [
(AndroidSupportInjectionModule::class),
(BroadcastReceiverModule::class)
])
interface AppComponent : AndroidInjector<MyApp> {
@Component.Builder
abstract class Builder : AndroidInjector.Builder<MyApp>()
}
La classe Application
class MyApp : DaggerApplication() {
override fun applicationInjector(): AndroidInjector<MyApp> =
DaggerAppComponent.builder().create(this@MyApp)
}
La classe BroadcastReceiver
class MyTestReceiver : BroadcastReceiver() {
@Inject
lateinit var anInjectedObject: MyInjectObject
override fun onReceive(context: Context, intent: Intent) {
AndroidInjection.inject(this, context)
anInjectedObject.doSomthing()
}
}
Vous pouvez utiliser DaggerBroadcastReceiver ou vous pouvez remplacer la méthode onReceive comme ci-dessous:
public void onReceive(Context context, Intent intent) {
AndroidInjection.inject(this, context);
// your code should be here ...
}
documents de poignard: https://dagger.dev/api/2.24/dagger/Android/DaggerBroadcastReceiver