Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/193.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何注入广播接收机_Android_Dependency Injection_Broadcastreceiver_Dagger - Fatal编程技术网

Android 如何注入广播接收机

Android 如何注入广播接收机,android,dependency-injection,broadcastreceiver,dagger,Android,Dependency Injection,Broadcastreceiver,Dagger,是否有人已经必须使用dagger将一个已经存在的类和一些业务逻辑注入到BroadcastReceiver中 我正在使用dagger 1,并且已经找到了一个很好的示例(),但是,我找不到如何将一个已经存在的类(属于另一个模块)添加到BroadcastReceiver中 任何帮助或建议都将不胜感激。我通过定义一个模块将用例注入到广播中,该模块提供了我需要的用例,我在onReceive方法中添加了该模块,请检查下面的代码: My广播接收模块: @Module(injects = { MyBroadca

是否有人已经必须使用dagger将一个已经存在的类和一些业务逻辑注入到BroadcastReceiver中

我正在使用dagger 1,并且已经找到了一个很好的示例(),但是,我找不到如何将一个已经存在的类(属于另一个模块)添加到BroadcastReceiver中


任何帮助或建议都将不胜感激。

我通过定义一个模块将用例注入到广播中,该模块提供了我需要的用例,我在onReceive方法中添加了该模块,请检查下面的代码:

My广播接收模块

@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;
    }
}
@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;
}
我的广播接收器

@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;
    }
}
@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;
}
@injectmyutilsclass MyUtilsClass;
@注射MyUseCase-MyUseCase;
@重写公共void onReceive(上下文、意图){
AcidApplication.getScopedGraph(getModules().toArray()).inject(this);
myUseCase.call();
myUtilsClass.doSomething();
}
受保护的列表getModules(){
列表结果=新建ArrayList();
添加(新的BroadcastReceiverModule());
返回结果;
}

与注入活动相同

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

回答这个问题可能太晚了,但我将提供我最近项目中的一个例子,我在其中尝试注入
AppWidgetProvider
,它是
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);
    }
}
class MyReceiver : DaggerBroadcastReceiver() {

    @Inject
    lateinit var repository: MyRepository

    override fun onReceive(context: Context?, intent: Intent?) {
        super.onReceive(context, intent)
        // Do your stuff...
    }
}
为带有注释为
@ContributesAndroidInjector
的抽象方法的创建另一个抽象
@Module
,该抽象方法返回要注入的
广播接收器
s:

/**
 * To inject the app widgets.
 */
@Module
public abstract class WidgetsModule {
    @ContributesAndroidInjector
    abstract IngredientsWidget contributesIngredientsWidget();
}
如果您忘记添加此模块,将出现如下错误:

java.lang.IllegalArgumentException:没有针对的喷油器工厂绑定 阶级

然后是组件和两个模块

然后在
应用程序
类中实现
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;
    }
}
您可以找到有关如何注入android组件的更多信息


我构建了一个小示例:.

匕首2示例,用于将对象注入广播接收器。

广播接收模块.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>()
}

您可以使用DaggerBroadcastReceiver或重写onReceive方法,如下所示:

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

虽然有点晚了,但与前面的答案相比,我有一点改进,您不需要显式调用
AndroidInjection.inject(这里是上下文)
onReceive
方法中

这是接收器,因此您不必这样做,技巧是从
DaggerBroadcastReceiver
扩展:

@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);
    }
}
class MyReceiver : DaggerBroadcastReceiver() {

    @Inject
    lateinit var repository: MyRepository

    override fun onReceive(context: Context?, intent: Intent?) {
        super.onReceive(context, intent)
        // Do your stuff...
    }
}

其余的都是一样的注册模块等等。我希望这会有帮助:D

知道如何测试吗?这就是我喜欢的Stackoverflow答案:示例说明,链接到文档和GitHub上的示例项目-谢谢@amrro!注意-这是匕首1。这是2019年的正确方法。但是,您可以通过简单地让应用程序类扩展
DaggerApplication
和接收器扩展
DaggerBroadcastReceiver
@s-hunter来保存最后两个步骤。是否也可以将
BroadcastReceiverModule
定义为
接口?你能解释一下为什么你选择了一个
抽象类
?非常感谢。我们是否保证应用程序上下文始终是应用程序实例?如果不是,这不是一个可接受的答案。