2015-11-30 20 views
5

Qualcuno ha già dovuto iniettare una classe già esistente, con qualche logica aziendale, in un BroadcastReceiver usando il pugnale?Come iniettare in un BroadcastReceiver

Sto usando dagger 1 e ho già trovato un buon esempio (https://github.com/adennie/fb-android-dagger) ma, non sono riuscito a trovare come aggiungere una classe già esistente, che appartiene a un modulo diverso, in un BroadcastReceiver.

Qualsiasi aiuto o consiglio sarebbe molto apprezzato.

risposta

1

sono riuscito a iniettare casi d'uso nel mio Broadcast definendo un modulo che forniscono i casi d'uso di cui ho bisogno e ho aggiungere il modulo sul metodo OnReceive, controllare il codice qui sotto:

mio BroadcastReceiverModule:

@Module(injects = { MyBroadcastReceiver.class }, addsTo = MyAppModule.class) 
public class BroadcastReceiverModule { 
    @Provides @Singleton MyUtilsClass providesMyUtilsClass(MyUtilsClassImpl myUtilsClass) { 
     return myUtilsClass; 
    } 
    @Provides @Singleton MyUseCase providesMyUseCase(MyUseCaseImpl myUseCaseUtils) { 
     return myUseCaseUtils; 
    } 
} 

mio BroadCastReceiver:

@Inject MyUtilsClass myUtilsClass; 
@Inject MyUseCase myUseCase; 
@Override public void onReceive(Context context, Intent intent) { 
    AcidApplication.getScopedGraph(getModules().toArray()).inject(this); 
    myUseCase.call(); 
    myUtilsClass.doSomething(); 
} 
protected List<Object> getModules() { 
    List<Object> result = new ArrayList<>(); 
    result.add(new BroadcastReceiverModule()); 
    return result; 
} 
12

Come te iniettare ad un'attività

public void onReceive(Context context, Intent intent) { 
     ((Application) context.getApplicationContext()).getInjector().inject(this); 
    } 
2

Potrebbe essere troppo tardi per rispondere a questa domanda, ma mi fornirà un esempio dal mio recente progetto in cui ho cercato di iniettare AppWidgetProvider che è una sottoclasse diretta di BroadcastReceiver.

Abbiamo bisogno di iniettare un servizio di retrofit in un BroadcastReceiver:

@Module 
public class NetModule { 
    /** shrunk for simplicity's sake. **/ 
    @Singleton 
    @Provides 
    public WidgetService provideWidgetService(Application application, OkHttpClient client, Gson gson) { 
     return new Retrofit.Builder() 
       .addConverterFactory(GsonConverterFactory.create(gson)) 
       .baseUrl(application.getString(R.string.api_url)) 
       .client(client) 
       .build() 
       .create(WidgetService.class); 
    } 
} 

Creare un altro astratto @Module per la con metodi astratti annotati con @ContributesAndroidInjector che restituiscono BroadcastReceiver s si vuole iniettare:

/** 
* To inject the app widgets. 
*/ 
@Module 
public abstract class WidgetsModule { 
    @ContributesAndroidInjector 
    abstract IngredientsWidget contributesIngredientsWidget(); 
} 

Se hai dimenticato di aggiungere questo modulo, riceverai un errore del tipo:

java.lang.IllegalArgumentException: No fabbrica iniettore diretto a Classe <>

Poi il componente con entrambi i moduli, oltre AndroidInjectionModule

@Singleton 
@Component(modules = {AndroidInjectionModule.class, NetModule.class, WidgetsModule.class}) 
public interface AppComponent { 
    void inject(RecipesApp recipesApp); 
} 

Poi nella classe Application di implementare HasBroadcastReceiverInjector interfaccia.

public class RecipesApp extends Application implements HasBroadcastReceiverInjector { 

    @Inject 
    DispatchingAndroidInjector<BroadcastReceiver> broadcastReceiverInjector; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     component().inject(this); 
    } 

    public AppComponent component() { 
     return DaggerAppComponent.builder() 
       .build(); 
    } 

    @Override 
    public AndroidInjector<BroadcastReceiver> broadcastReceiverInjector() { 
     return broadcastReceiverInjector; 
    } 
} 

Infine, è possibile iniettare il BroadcastReceiver all'interno OnReceive() prima di chiamare super().

public class IngredientsWidget extends AppWidgetProvider { 

    @Inject 
    public WidgetService api; 


    @Override 
    public void onReceive(Context context, Intent intent) { 
     /** Don't forget this line **/ 
     AndroidInjection.inject(this, context); 
     super.onReceive(context, intent); 
    } 

} 

È possibile trovare maggiori informazioni su come iniettare componenti Android docs.

Ho creato un piccolo campione: broadcast-injection.

Problemi correlati