2016-09-28 113 views
6

我正在尝试将inject dependencies插入我的应用程序。一切工作正常,直到我试图将Realm注入到我的Service类中。我开始得到IllegalStateException,这显然是由我创建的Thread访问Realm造成的。所以,这是我的Dependency Injection依赖注入服务

结构,而AppModule

@Module 
public class AppModule { 

    MainApplication mainApplication; 

    public AppModule(MainApplication mainApplication) { 
     this.mainApplication = mainApplication; 
    } 

    @Provides 
    @Singleton 
    MainApplication getFmnApplication() { 
     return mainApplication; 
    } 
} 

的RequestModule

@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()); 
    } 
} 

的AppComponent

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

    void inject(SyncService suncService); 
} 

应用程序类

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; 
    } 
} 

GeneralAPIHandler

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 
    } 
} 

这仅当我从Service class调用它发生,但它是与应用程序上下文创建。为什么什么我做错了要制作RealmIllegalStateException将不胜感激抛出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){} 
     }) 
    } 
} 

任何帮助。由于

回答

6
​​

也因此

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后台线程运行

Yo你也不会关闭Realm实例,尽管它处在一个非循环的后台线程中,所以它对你造成了很大的影响。


解决方案,你应该在onHandleIntent()取得领域实例,并在执行结束时关闭它在finally {


你可能会说,“但后来我将如何嘲笑我的构造函数参数”,答案是使用一类像

@Singleton 
public class RealmFactory { 
    @Inject 
    public RealmFactory() { 
    } 

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

谢谢你清除这部分。 '@Override public void onCreate(){ super.onCreate(); ((MainApplication)getApplicationContext())。getMainAppComponent()。inject(this); }' –

1

一个领域实例需要从它创建的线程只能访问。

你的意图的服务在后台线程中运行。你的境界很可能在主线程中创建

+0

我知道这不过是什么意思。那么,你是说'MainThread'上的'ApplicationContext'与'BackgroundThread'中的'ApplicationContext'不同? –

+2

不,他的意思是'onCreate()'在UI线程上运行,'onHandleIntent()'在后台线程上 – EpicPandaForce