2016-09-28 155 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