2017-08-11 2 views
0

Je suis nouveau à Dagger2 et j'essaie d'utiliser l'injection de dépendance dans mon application. J'utilise des préférences partagées et je pensais qu'il serait plus utile d'utiliser l'injection de dépendance au lieu d'avoir une instance de préfrences partagées chaque fois que je dois l'utiliser. Cela fonctionne très bien quand je l'utilise sur des activités et des fragments, mais quand j'essaie de l'utiliser sur le service ou intentservice cela ne fonctionne pas.Android Dagger2 dépendance injection

Voici mon code:

AppModule:

@Module 
public class AppModule 
{ 
    public final ApplicationClass application; 

    public AppModule(ApplicationClass application) 
    { 
     this.application = application; 
    } 

    @Provides @Singleton 
    Context providesApplicationContext() 
    { 
     return this.application; 
    } 

    @Provides @Singleton 
    SharedPreferences providesSharedPreferences() 
    { 
     return application.getSharedPreferences(Constants.FILE_NAME,Context.MODE_PRIVATE); 
    } 
} 

AppComponent

@Singleton @Component(modules = {AppModule.class}) 
public interface AppComponent 
{ 
    void inject (ApplicationClass applicationClass); 
    void inject (IntentService intentService); 
    void inject (Service service); 
} 

ApplicationClass

public class ApplicationClass extends Application 
{ 
    AppComponent appComponent; 

    @Override 
    public void onCreate() 
    { 
     super.onCreate(); 
     Thread.setDefaultUncaughtExceptionHandler(new 
     Thread.UncaughtExceptionHandler() { 
      @Override 
      public void uncaughtException(Thread t, Throwable e) { 
       onUncaughtException(t, e); 
      } 
     }); 

     appComponent = DaggerAppComponent 
         .builder() 
         .appModule(new AppModule(this)) 
         .build(); 

     appComponent.inject(this); 
    } 

    public AppComponent getAppComponent() 
    { 
     return this.appComponent; 
    } 

    private void onUncaughtException(Thread t, Throwable e) 
    { 
     e.printStackTrace(); 

     Intent crash= new Intent(getApplicationContext(),Crash.class); 
     about.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     startActivity(crash);  
    } 
} 

J'ai donc essayé d'injecter les préférences partagées dans IntentService et moi ces lignes de code dans la méthode onCreate du mon service (intentservice)

@Inject 
SharedPreferences preferences; 

@Override 
public void onCreate() 
{ 
    super.onCreate(); 
    ((ApplicationClass)getApplication()).getAppComponent().inject(this); 
} 

Mais le problème est quand j'utilise ce préférences variable dans la méthode onHandleIntent, l'application plante parce que les préférences sont nulles .. Alors pourquoi ne pas injecter?

+1

Vous n'avez pas besoin d'injecter le contexte et les préférences partagées dans IntentService, IntentService a déjà hérité de Context. Votre problème est que vous devriez utiliser le nom de la classe cible (dans la méthode d'injection) dans AppComponent par exemple: 'void inject (ApplicationClass applicationClass); void injecter (CustomIntentService intentionService); void injecter (service SimpleIntentService); ' – Onregs

+1

Vous devez spécifier une ** classe concrète spécifique ** et non sa classe parente pour y injecter. Donc, vous ne pouvez pas simplement dire 'IntentService' et injecter dans n'importe quel service d'intention, ce sera null parce que votre classe n'est pas' IntentService', c'est 'WhateverService'. – EpicPandaForce

+0

@VadimKorzun merci comme vous pouvez le voir, je voulais dire des préférences partagées et édité ma question. Merci pour votre clarification sur mon problème – Elior

Répondre

0

Pour tous ceux qui ont rencontré ce problème. Comme Vadim Korzun et EpicPandaForce mentionné dans leurs commentaires ci-dessus, je devrais spécifier la classe spécifique dans la méthode d'injection.

Donc dans mon cas ma classe IntentService a été nommé GeofenceService

et à l'intérieur de l'interface AppComponent je devrais écrire

void inject (GeofenceService service); 

Même chose pour Service

MISE À JOUR:

Alors pour toutes les personnes qui ont plusieurs services héritent de IntentService et veulent se sauver de l'écriture de la méthode d'injection pour chaque service spécifique. Je suggère de faire les étapes ci-dessous:

  1. Créer BasicIntentService qui étendIntentService
  2. Dans votre interface AppComponent ajouter la méthode d'injection qui prennent comme paramètre BasicIntentService.
  3. Dans votre BasicIntentSerive, vous aurez une variable protected SharedPrefrences annotée avec l'annotation Inject.
  4. Pourtant, dans votre BasicIntentService, dans la méthode onCreate vous appeler cette ligne de code

    ((ApplicationClass) getApplication()) getAppComponent() injecter (ce)..

  5. Maintenant, chaque IntentService que vous allez créer étend le BasicIntentService et vous serez en mesure d'utiliser la variable SharedPreferences.


AppComponent:

@Singleton @Component(modules = {AppModule.class}) 
public interface AppComponent 
{ 
    void inject (YourApplicationClass applicationClass); 
    void inject (BasicIntentService intentService); 
} 

BasicIntentService

public class BasicIntentService extends IntentService 
{ 
    @Inject 
    protected SharedPreferences sharedPreferences; 

    @Override 
    public void onCreate() 
    { 
     super.onCreate() 
     ((YourApplicationClass)getApplication()).getAppComponenet().inject(this); 
    } 
} 

SomeIntentService
public class SomeIntentService extends BasicIntentService 
{ 
    @Override 
    public void onCreate() 
    { 
     super.onCreate(); 
    } 
    ----------- 
    @Override 
    protected void onHandleIntent(@Nullable Intent intent) 
    { 
    // some code 
    if (sharedPreferences.contains(someKey)) 
    { 
     // some code 
    } 
    else 
    { 
     // some code 
    } 
    } 

}