依赖注入服务

时间:2016-09-28 17:57:25

标签: android realm dagger-2

我正在尝试inject dependencies进入我的应用程序。在我尝试将Realm注入我的Service课程之前,一切正常。我开始收到IllegalStateException,这显然是因为我从Realm创建的Thread访问了Dependency Injection。所以,这是我的@Module public class AppModule { MainApplication mainApplication; public AppModule(MainApplication mainApplication) { this.mainApplication = mainApplication; } @Provides @Singleton MainApplication getFmnApplication() { return mainApplication; } }

的结构

AppModule

@Module
public class RequestModule {

    @Provides
    @Singleton
    Retrofit.Builder getRetrofitBuilder() {
        return new Retrofit.Builder()
                .baseUrl(BuildConfig.HOST)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(CustomGsonParser.returnCustomParser()));
    }

    @Provides
    @Singleton
    OkHttpClient getOkHttpClient() {
        return new OkHttpClient.Builder()
                .addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC))
                .connectTimeout(30000, TimeUnit.SECONDS)
                .readTimeout(30000, TimeUnit.SECONDS).build();
    }

    @Provides
    @Singleton
    Retrofit getRetrofit() {
        return getRetrofitBuilder().client(getOkHttpClient()).build();
    }

    @Provides
    @Singleton
    ErrorUtils getErrorUtils() {
        return new ErrorUtils();
    }

    @Provides
    @Singleton
    MainAPI getMainAPI() {
        return getRetrofit().create(MainAPI.class);
    }

    // Used in the Service class
    @Provides
    @Singleton
    GeneralAPIHandler getGeneralAPIHandler(MainApplication mainApplication) {
        return new GeneralAPIHandler(mainApplication, getMainAPIHandler(), getErrorUtils());
    }
}

RequestModule

@Singleton
@Component(modules = {
        AppModule.class,
        RequestModule.class
})
public interface MainAppComponent {

    void inject(SyncService suncService);
}

AppComponent

public class MainApplication extends Application {

    private MainAppComponent mainAppComponent;

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mainAppComponent = DaggerMainAppComponent.builder()
                .appModule(new AppModule(this))
                .requestModule(new RequestModule())
                .build();
    }

    public MainAppComponent getMainAppComponent() {
        return mainAppComponent;
    }
}

应用程序类

public class GeneralAPIHandler {

    private static final String TAG = "GeneralAPIHandler";
    private MainAPI mainAPI;
    private Realm realm;
    private ErrorUtils errorUtils;
    private Context context;

    public GeneralAPIHandler() {
    }

    public GeneralAPIHandler(MainApplication mainApplication, MainAPI mainAPI, ErrorUtils errorUtils) {
        this.mainAPI = mainAPI;
        this.realm = RealmUtils.getRealmInstance(mainApplication.getApplicationContext());
        this.errorUtils = errorUtils;
        this.context = mainApplication.getApplicationContext();
    }

    public void sendPayload(APIRequestListener apiRequestListener) {
        List<RealmLga> notSentData = realm.where(RealmLga.class).equalTo("isSent", false).findAll(); <-- This is where the error comes from

        .... Other code here
    }
}

GeneralAPIHandler

Service class

只有当我从IllegalStateException调用它时才会发生这种情况但是,它是使用应用程序上下文创建的。为什么要抛出public class SyncService extends IntentService { @Inject GeneralAPIHandler generalAPIHandler; @Override public void onCreate() { super.onCreate(); ((MainApplication) getApplicationContext()).getMainAppComponent().inject(this); } /** * Creates an IntentService. Invoked by your subclass's constructor. */ public SyncService() { super("Sync"); } @Override protected void onHandleIntent(Intent intent) { sendInformations(); } private void sendInformations() { generalAPIHandler.sendPayload(new APIRequestListener() { @Override public void onError(APIError apiError){} @Override public void didComplete(WhichSync whichSync){} }) } }

服务类

Realm

对于IllegalStateException抛出{{1}}我做错了什么的任何帮助都将不胜感激。感谢

2 个答案:

答案 0 :(得分:9)

@Inject GeneralAPIHandler generalAPIHandler;

@Override
public void onCreate() {
    super.onCreate();
    ((MainApplication) getApplicationContext()).getMainAppComponent().inject(this);
}

因此

public GeneralAPIHandler(MainApplication mainApplication, MainAPI mainAPI, ErrorUtils errorUtils) {
    this.mainAPI = mainAPI;
    this.realm = RealmUtils.getRealmInstance(mainApplication.getApplicationContext()); // <--

此代码在UI线程上运行

@Override
protected void onHandleIntent(Intent intent) {
    sendInformations();
}

private void sendInformations() {
    generalAPIHandler.sendPayload(new APIRequestListener() {
    ....


public void sendPayload(APIRequestListener apiRequestListener) {
    List<RealmLga> notSentData = realm.where(RealmLga.class).equalTo("isSent", false).findAll();

此代码在IntentService后台线程

上运行

你也不会关闭Realm实例,尽管它仍然是一个非循环的后台线程,所以它通过崩溃帮你一个忙。

解决方案,您应该在onHandleIntent()中获取Realm实例,并在执行结束时在finally {中关闭它。

您可能会说,&#34;但是我将如何模拟我的构造函数参数&#34;,答案是使用像

这样的类
@Singleton
public class RealmFactory {
    @Inject
    public RealmFactory() {
    }

    public Realm create() {
        return Realm.getDefaultInstance();
    }
}

答案 1 :(得分:2)

只需从其创建的线程中访问领域实例。

您的意图服务在后台线程中运行。您的领域可能是在主线程上创建的