Android 在Dagger 2中异步构造依赖关系图

Android 在Dagger 2中异步构造依赖关系图,android,asynchronous,dagger-2,Android,Asynchronous,Dagger 2,这是一个更具理论性的问题。如果我走错了方向,请告诉我 有没有办法在Dagger 2中异步/并行加载一些图形依赖项?它甚至应该在匕首的背景下考虑吗 我的问题主要与应用程序启动时间有关。许多外部依赖项,如Mixpanel、Crashlytics/Fabric、改装(RestaAdapter),都会导致应用程序的预热时间超过1秒 对我帮助很大的是懒惰的界面,但最终的效果仍然不能让我满意 有什么想法吗 示例 应用程序有SplashActivity,它依赖于SplashActivityPresenter,

这是一个更具理论性的问题。如果我走错了方向,请告诉我

有没有办法在Dagger 2中异步/并行加载一些图形依赖项?它甚至应该在匕首的背景下考虑吗

我的问题主要与应用程序启动时间有关。许多外部依赖项,如Mixpanel、Crashlytics/Fabric、改装(RestaAdapter),都会导致应用程序的预热时间超过1秒

对我帮助很大的是懒惰的界面,但最终的效果仍然不能让我满意

有什么想法吗

示例

应用程序有SplashActivity,它依赖于SplashActivityPresenter,它依赖于:Mixpanel、RestAdapter和Crashlytics库(以及一些“较小”的对象)。每个都有.init()方法,这需要很多时间(在Nexus5、Android M上,Mixpanel初始化大约需要200毫秒。因此,在用户看到闪屏之前,大约需要2秒钟


有没有办法并行构造这些对象?

Dagger 2的对象图创建没有什么特别之处。如果希望在后台线程中完成,只需在后台线程上调用
DaggerYourComponent.create()
DaggerYourComponent.Builder()
(使用您首选的方法执行此操作-例如,异步任务)


如果您有任何
@Inject
构造函数假定它们将在UI线程上运行,那么您必须修改这些构造函数,否则您不应该有任何问题。

保持图形创建同步并延迟对象创建,直到使用Rx的延迟订阅。在ob上,可以通过主题通知下游注入这是我的创作

@Module public static class AppModule{

    @Provides @Singleton
    public Observable<A> provideA(){
        return Observable.defer(
                () -> Observable.just(new A()) 
        );
    }
}
@Module公共静态类AppModule{
@提供@Singleton
公共可观测provideA(){
返回可观察的延迟(
()->可观察到。只是(新的A())
);
}
}

public类MainActivity扩展了AppCompatActivity{
@注入可观察的aObservable;
A A;
AppComponent AppComponent;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
把(这个)绑起来;
如果(appComponent==null){
appComponent=((应用程序)getApplication())
.getAppComponent();
}
appComponent.inject(这个);
aObservable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.订阅(新操作1(){
@覆盖公共作废调用(最终A aa){
a=aa;
Log.d(“主要活动”,“a=aa”);
}
});
}
}

注意事项:必须手动检查object!null,或依赖于充当eventbus的主题,这将传递下游注入对象必须等待的对象的布尔状态。

如果我错了,请更正我,但Dagger 2依赖于生成的代码,因此不应影响启动时间。图形合成在编译时完成,但对象创建是在运行时进行的。因此,对象初始化(构造和可选配置)是在我们启动应用程序之后进行的(在我们第一次注入它们的时候)。为什么您的splash活动依赖于这些库?它真的需要吗?如果不需要,那么您可以在创建这些对象之前显示splash,但这并不能解决问题。2sec甚至对于splash screen imho来说也很长。它只是用于描述问题的依赖关系图的简化版本。在实际解决方案中,它将是:Presenter Dependent在AnalyticsManager上,UserManager。AnalyticsManager依赖于GoogleAnalytics和Mixpanel,UserManager依赖于LocalStoreManager和RestAdapter。等等……我知道了,但我不明白为什么您需要在SplashActivity中包含所有这些。SplashActivity难道不能是一个没有依赖项的简单活动并创建所有管理器吗什么是在创建之后?对象构造的位置不是我关心的问题。我必须面对的主要问题是图形是一个接一个地构造的。应用程序启动需要200ms的Mixpanel.init+200ms的Crashlytics.init+200ms的RestAdapter.init+(…)我想一次并行构造这些对象。你可能想更新你的问题-你要求的是异步构造,而不是并行构造。异步我指的是一次不止一件事,而不是在另一个线程上(因为我认为它仍然是同步的)@froger_mcs我同意vaughandroid,你的问题确实表明你想以某种方式在后台线程中完成所有事情,并推迟应用程序/活动/组件的创建。如果你想并行调用
init
s,为什么不把它们放在单独的模块中,在后台调度程序中创建它们,并与RxJava结合,一次得到3个呢?不能吗现在确实要提供正确的答案,但我相信如果你编辑了你的问题,它会更清楚你想要实现什么。这个解决方案对我来说是一个好方法,但在这种情况下,你应该关心尚未初始化的对象,正如你所提到的。当你使用一些依赖项一次时,它会起作用,但当你在任何地方都应该关心它时(例如,用于某些活动、演示者、服务等)应在其他地方进行非空检查。我正在为此制定临时解决方案,但最终的决赛可能需要一些注释处理。
public class MainActivity extends AppCompatActivity{

    @Inject Observable<A> aObservable;
    A a;
    AppComponent appComponent;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        if(appComponent == null){ 
            appComponent = ((App) getApplication())
                .getAppComponent(); 
        }
        appComponent.inject(this);

        aObservable.subscribeOn(Schedulers.io())
                   .observeOn(AndroidSchedulers.mainThread())
                   .subscribe(new Action1<A>(){
                       @Override public void call(final A aa){
                           a = aa;
                           Log.d("MainActivity", "a = aa");
                       }
                   });
    }
}