是否有人必须使用匕首将已存在的类(带有一些业务逻辑)注入BroadcastReceiver?
I' M使用匕首1和已经找到了一个很好的例子(https://github.com/adennie/fb-android-dagger),但是,我无法找到如何才能一个已经存在的类,属于添加到不同的模块,进入一个BroadcastReceiver。
非常感谢任何帮助或建议。
答案 0 :(得分:20)
与注入活动相同
public void onReceive(Context context, Intent intent) {
((Application) context.getApplicationContext()).getInjector().inject(this);
}
答案 1 :(得分:15)
回答这个问题可能为时已晚,但我将从我最近的项目中提供一个示例,我尝试注入AppWidgetProvider
BroadcastReceiver
的直接子类。
我们需要在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);
}
}
为带有@Module
注释的抽象方法创建另一个抽象@ContributesAndroidInjector
,返回BroadcastReceiver
你要注入的内容:
/**
* To inject the app widgets.
*/
@Module
public abstract class WidgetsModule {
@ContributesAndroidInjector
abstract IngredientsWidget contributesIngredientsWidget();
}
如果您忘记添加此模块,您将收到如下错误:
之外的具有两个模块的组件java.lang.IllegalArgumentException:没有绑定的进程工厂 类<>
@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;
}
}
最后,您可以在调用super()之前将onReceive()内的BroadcastReceiver注入。
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组件docs的更多信息。
我制作了一个小样本:broadcast-injection。
答案 2 :(得分:3)
我设法通过定义一个提供我需要的用例的模块将用例注入我的广播,并在onReceive方法上添加Module,检查下面的代码:
我的 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;
}
答案 3 :(得分:2)
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(this@MyApp)
}
BroadcastReceiver类
class MyTestReceiver : BroadcastReceiver() {
@Inject
lateinit var anInjectedObject: MyInjectObject
override fun onReceive(context: Context, intent: Intent) {
AndroidInjection.inject(this, context)
anInjectedObject.doSomthing()
}
}
答案 4 :(得分:0)
您可以使用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
答案 5 :(得分:0)
有点太晚了,但我比之前的答案略有改进,您不需要在 AndroidInjection.inject(this, context);
方法中显式调用 onReceive
。
这是接收器,因此您不必这样做,诀窍是从 DaggerBroadcastReceiver
扩展:
class MyReceiver : DaggerBroadcastReceiver() {
@Inject
lateinit var repository: MyRepository
override fun onReceive(context: Context?, intent: Intent?) {
super.onReceive(context, intent)
// Do your stuff...
}
}
其余的与注册模块等相同。我希望它有所帮助:D