Java 如何使用Dagger 2将对象注入Android优先级作业队列?
我正试图通过使用Dagger2集成改造2和Android优先级作业队列 我可能在这里使用了错误的模式(我是Java和Android新手),但我试图从一个对象访问Dagger创建的改造实例,该对象将被序列化,然后在执行前反序列化(Android作业队列序列化持久化到磁盘的作业)。改型实例是由应用程序Dagger组件创建的,因为我在它的一个依赖项中使用了SharedReferences 我无法在创建作业时将改装传递给作业,因为改装本身无法序列化 应用程序也无法序列化,因此我无法在作业运行时引用作业中的应用程序Dagger组件(因为我无法使用Java 如何使用Dagger 2将对象注入Android优先级作业队列?,java,android,serialization,dagger,dagger-2,Java,Android,Serialization,Dagger,Dagger 2,我正试图通过使用Dagger2集成改造2和Android优先级作业队列 我可能在这里使用了错误的模式(我是Java和Android新手),但我试图从一个对象访问Dagger创建的改造实例,该对象将被序列化,然后在执行前反序列化(Android作业队列序列化持久化到磁盘的作业)。改型实例是由应用程序Dagger组件创建的,因为我在它的一个依赖项中使用了SharedReferences 我无法在创建作业时将改装传递给作业,因为改装本身无法序列化 应用程序也无法序列化,因此我无法在作业运行时引用作业中
((MyApplication)MyApplication).component().inject(此);
进行注入,就像我可以从活动中进行注入一样,因为反序列化作业中不存在应用程序对象。)
为了提高效率,我想使用应用程序其余部分使用的改装实例,而不是仅仅为作业创建另一个实例。有可能吗
我不确定使用Provider
或工厂是否会有所帮助,因为这超出了我现在的理解范围,但如果是这样的话,我希望得到一个关于如何构建事物的提示
编辑:这是使用Android优先级作业队列创建作业的方法。我修改了一个样本,以表明我希望注射的效果如何。作业在onAdded()
上序列化,并在使用onRun()运行之前反序列化:
这是我能处理的最简单的解决方案
首先,创建一个BaseJob
类。这将是注射目标:
public abstract class BaseJob extends Job {
// annotate fields that should be injected and made available to subclasses
@Inject MyService service;
protected BaseJob(Params params) {
super(params);
}
}
它被声明为abstract
,因此不需要重写Job
类中声明的任何抽象方法。相反,将在继承自BaseJob
的作业中重写方法
创建从BaseJob
继承的作业。注入BaseJob
的任何字段都可以使用:
public class MyActualJob extends BaseJob {
public static final int PRIORITY = 1;
public MyActualJob() {
super(new Params(PRIORITY).requireNetwork().persist());
}
@Override
public void onAdded() {
// job added to queue
}
@Override
public void onRun() throws Throwable {
// do the work
// service will be injected into BaseJob, so you can use it here
final Call<User> call = service.getUser();
call.execute();
}
@Override
protected void onCancel() {
// clean up
}
}
为什么不跳过使用BaseJob
,直接注入MyActualJob
?但是,如果有多个作业是注入目标,我相信您必须使用instanceof
检查正在创建的作业类型,并在创建DependencyInjector
时将job
转换为正确的类:
DependencyInjector dependencyInjector = new DependencyInjector() {
@Override
public void inject(Job job) {
if (job instanceof MyActualJob) {
((MyApplication) app).component().inject((MyActualJob) job);
} else if (job instanceof MyRealJob) {
((MyApplication) app).component().inject((MyRealJob) job);
} else if (job instanceof MyBetterJob) {
((MyApplication) app).component().inject((MyBetterJob) job);
}
}
};
在我的例子中,大多数作业(如果不是所有作业的话)都需要访问相同的全局对象,因此将BaseJob
子类化并将其用作唯一注入目标更为简洁。一般来说,您通常会序列化模型/简单类。为什么他们甚至需要访问改装实例?添加一个管理器/演示器/处理程序类来执行后端调用并保持模型(您的序列化类)没有选项吗?@DavidMedenjak我添加了一些示例代码来显示Android优先级作业队列的情况。当作业运行时,我需要从作业中调用我的服务(或改装)。库的自述文件显示通过添加注入器支持DI,您已经尝试过了吗?这似乎是最干净的解决方法go@DavidMedenjak在发布这个问题之前,我已经试过了,但在弄清楚如何准确地使用它时遇到了一些困难。在你发表评论后,我又看了一眼,想出了一些可能并不完美但能很好地满足我需要的东西。我会在一天左右发布一个完整的例子。谢谢你把我推向正确的方向!嘿,如果每个作业使用不同的服务怎么办?我会为每个作业创建一个BaseJob吗?不,您会将服务添加到BaseJob:@InjectDifferentitService;或者执行if语句检查并注入新作业
DependencyInjector dependencyInjector = new DependencyInjector() {
@Override
public void inject(Job job) {
// this line depends on how your Dagger components are setup;
// the important part is to cast job to BaseJob
((MyApplication) app).component().inject((BaseJob) job);
}
};
Configuration configuration = new Configuration.Builder(getApplicationContext())
.injector(dependencyInjector)
.build();
JobManager jobManager = new JobManager(getApplicationContext(), configuration);
DependencyInjector dependencyInjector = new DependencyInjector() {
@Override
public void inject(Job job) {
if (job instanceof MyActualJob) {
((MyApplication) app).component().inject((MyActualJob) job);
} else if (job instanceof MyRealJob) {
((MyApplication) app).component().inject((MyRealJob) job);
} else if (job instanceof MyBetterJob) {
((MyApplication) app).component().inject((MyBetterJob) job);
}
}
};