Inyección de dependencia en servicio
Estoy tratando de inject dependencies
en mi aplicación. Todo funciona bien hasta que intento inyectar Realm
en mi clase de Service
. Empecé a obtener IllegalStateException
que obviamente es causada por mi acceso a Realm
de un Thread
que se creó. Por lo tanto, esta es la estructura de mi Dependency Injection
El AppModule
- Prueba de unidad de reino en Android
- Json cadena de objetos de reino, el camino más rápido
- ¿Cómo encubierta realmResult a la matriz y pasar a otra actividad?
- Getter no está asociado a ningún campo - Realm
- Realm.io Query con GroupBy
@Module public class AppModule { MainApplication mainApplication; public AppModule(MainApplication mainApplication) { this.mainApplication = mainApplication; } @Provides @Singleton MainApplication getFmnApplication() { return mainApplication; } }
El 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()); } }
El AppComponent
@Singleton @Component(modules = { AppModule.class, RequestModule.class }) public interface MainAppComponent { void inject(SyncService suncService); }
Clase de Aplicación
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 } }
Esto sólo ocurre cuando lo llamo de una Service class
pero, se creó con el contexto de aplicación. ¿Por qué está lanzando una IllegalStateException
La clase de servicio
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){} }) } }
Cualquier ayuda en lo que estoy haciendo mal para hacer el lanzamiento del Realm
IllegalStateException
sería apreciada. Gracias
- Modo correcto de hacer la migración de Realm
- ¿Cómo sincronizar los datos del servidor en la aplicación android?
- ¿Existe una manera de pre-empaquetar la base de datos Realm (default.Realm) a través de React-Native (JS)
- Android Realm número de versión de migración basado en qué?
- Realm.io / Dagger / Databinding en el mismo proyecto
- Error: java.lang.UnsatisfiedLinkError con roboelectric y reino
- Android Realm: restricción de clave primaria rota. El valor ya existe: 0
- Cómo manejar la migración de dominios si los usuarios omitir las actualizaciones
@Inject GeneralAPIHandler generalAPIHandler; @Override public void onCreate() { super.onCreate(); ((MainApplication) getApplicationContext()).getMainAppComponent().inject(this); }
Y por lo tanto
public GeneralAPIHandler(MainApplication mainApplication, MainAPI mainAPI, ErrorUtils errorUtils) { this.mainAPI = mainAPI; this.realm = RealmUtils.getRealmInstance(mainApplication.getApplicationContext()); // <--
Este código se ejecuta en el subproceso de interfaz de usuario
@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();
Este código se ejecuta en el subproceso de fondo IntentService
Usted también no estaría cerrando la instancia de Realm a pesar de estar en un hilo de fondo no de bucle de todos modos, por lo que le hizo un favor por estrellarse.
Solución, debe obtener la instancia Realm en onHandleIntent()
y cerrarla finally {
al final de la ejecución.
Podrías decir, "pero entonces ¿cómo me burlaré de mi argumento Constructor", la respuesta es usar una clase como
@Singleton public class RealmFactory { @Inject public RealmFactory() { } public Realm create() { return Realm.getDefaultInstance(); } }
una instancia de reino debe tener acceso sólo desde el subproceso en el que se creó.
El servicio de intenciones se ejecuta en un subproceso de fondo. Su reino probablemente fue creado en el hilo principal
- La pantalla de bienvenida de Android no muestra la imagen a pantalla completa
- Causado por: java.lang.NoSuchFieldError: com.squareup.okhttp.internal.http.HttpMethod.METHODS cuando uso retrofit