Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.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
Java 如何使用Dagger 2将对象注入Android优先级作业队列?_Java_Android_Serialization_Dagger_Dagger 2 - Fatal编程技术网

Java 如何使用Dagger 2将对象注入Android优先级作业队列?

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 我无法在创建作业时将改装传递给作业,因为改装本身无法序列化 应用程序也无法序列化,因此我无法在作业运行时引用作业中

我正试图通过使用Dagger2集成改造2和Android优先级作业队列

我可能在这里使用了错误的模式(我是Java和Android新手),但我试图从一个对象访问Dagger创建的改造实例,该对象将被序列化,然后在执行前反序列化(Android作业队列序列化持久化到磁盘的作业)。改型实例是由应用程序Dagger组件创建的,因为我在它的一个依赖项中使用了SharedReferences

我无法在创建作业时将改装传递给作业,因为改装本身无法序列化

应用程序也无法序列化,因此我无法在作业运行时引用作业中的应用程序Dagger组件(因为我无法使用
((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);
        }
    }
};