使用Dagger 2注入服务

Ofe*_*mon 26 android dependency-injection inversion-of-control android-service dagger-2

我有一个应用程序,它基本上是一个一直运行的服务,并在发生事件时向用户发出警报.

当服务创建警报时,它需要将其发送给警报,context以便警报可以在发生事件时对服务进行回调.

例如:

public MyService extends Service{
    private SomeAlarm alarm;

    @Override
    public void onCreate() {
        super.onCreate();
        alarm = new SomeAlarm(MyService.this);
    }
}
Run Code Online (Sandbox Code Playgroud)

如何将SomeAlarm类注入服务,并将SomeAlarm服务上下文作为变量?

Dav*_*jak 39

我从头顶编写代码,所以可能会有一两个错字.

你这样做就像把东西注入活动一样.

  1. 声明一个组件,
  2. 将inject方法添加到该组件,
  3. 添加提供服务的模块
  4. 创建该组件构建器
  5. 将您的模块添加到构建器
  6. 使用组件注入您的服务

您的模块和组件看起来像这样(可能添加一些范围)

@Module
class ServiceModule {

    MyService mService;

    ServiceModule(MyService service) {
        mService = service;
    }

    @Provides
    MyService provideMyService() {
        return mService;
    }
}

@Component(modules=ServiceModule.class)
interface MyServiceComponent {
    void inject(MyService service);
}
Run Code Online (Sandbox Code Playgroud)

然后在onCreate创建组件并注入警报.

@Inject
private SomeAlarm alarm;

public void onCreate() {
    DaggerMyServiceComponent.builder()
            .serviceModule(new ServiceModule(this))
            .build()
            .inject(this);

    alarm.doStuff();
}
Run Code Online (Sandbox Code Playgroud)

这假设您的警报可以通过具有如下@Inject注释的构造函数来注入构造函数:

class SomeAlarm {
    @Inject
    SomeAlarm(MyService service) {
        /*constructor stuff*/
    }
}
Run Code Online (Sandbox Code Playgroud)

此外,您还可以将警报创建添加到模块中.

  • 感谢您的回答.代码不会编译,当我试图注入警报时,说"Builder()在Builder中有私人访问权限" (2认同)

pou*_*uya 17

我知道这个问题已经有了答案,但还有其他方法可以做到这一点

首先让你的应用程序HasServiceInjector像这样扩展:

public class App extends Application implements HasActivityInjector, 
HasServiceInjector {

@Inject
DispatchingAndroidInjector<Activity> dispatchingActivityInjector;
@Inject
DispatchingAndroidInjector<Service> dispatchingServiceInjector;

@Override
public void onCreate() {
    super.onCreate();
    AppInjector.init(this);
}

@Override
public AndroidInjector<Activity> activityInjector() {
    return dispatchingActivityInjector;
}

@Override
public AndroidInjector<Service> serviceInjector() {
    return dispatchingServiceInjector;
}

}
Run Code Online (Sandbox Code Playgroud)

然后创建一个ServiceBuilderModule这将在服务上执行注入:

@Module
abstract class ServiceBuilderModule {

@ContributesAndroidInjector
abstract MyService contributeMyService();

}
Run Code Online (Sandbox Code Playgroud)

然后将新模块注册到您的 component

@Component(modules = {
    AndroidSupportInjectionModule.class,
    AppModule.class,
    ActivityBuilderModule.class,
    ServiceBuilderModule.class
 })
 @Singleton
 public interface AppComponent {

 @Component.Builder
 interface Builder {
    @BindsInstance
    Builder application(App application);

    AppComponent build();
 }

 void inject(App app);

 }
Run Code Online (Sandbox Code Playgroud)

然后覆盖onCreate您的服务的方法并添加AndroidInjection.inject(this) 如下代码:

public class MyService extends Service {

@Override
public void onCreate() {
    AndroidInjection.inject(this);
    super.onCreate();
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

}
Run Code Online (Sandbox Code Playgroud)

代码kotlin是上面代码的精确转换。希望这能从现在开始帮助一些编码人员。