I'm learning to use otto as an event system. I can register my activity and receive the message from bus.post(). However, if I register my Application class, the subscribed method doesn't get called. What I'm I doing wrong?
This is my activity:
public class MainActivity extends AppCompatActivity {
#Inject
BusWorker busWorker;
#Inject
LogWorker logWorker;
ActivityMainBinding binding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
inject();
ButterKnife.bind(this);
busWorker.register(this);
binding.setHandlers(this);
}
#Subscribe
public void recievedMessage(Message message) {
logWorker.log("recievedMessage: " + message.getMessage());
}
public void onClickButton(View view) {
switch (view.getId()) {
case R.id.button:
busWorker.post("Test message");
break;
default:
break;
}
}
#Override
protected void onStop() {
super.onStop();
busWorker.unRegister(this);
}
void inject() {
((App) getApplication()).getGeneralComponent().inject(this);
((App) getApplication()).getSchoolComponent().inject(this);
}
}
App class
public class App extends Application {
private NetComponent netComponent;
private GeneralComponent generalComponent;
#Inject
public App() {}
#Override
public void onCreate() {
super.onCreate();
netComponent = DaggerNetComponent.builder()
.appModule(new AppModule(this))
.netModule(new NetModule())
.build();
generalComponent = DaggerGeneralComponent.builder()
.netComponent(netComponent)
.generalModule(new GeneralModule())
.build();
netComponent.BusWorker().register(this);
}
#Subscribe
public void recievedMessage(Message message) {
netComponent.logWorker().log("recievedMessage: " + message.getMessage());
}
public GeneralComponent getGeneralComponent() {
return generalComponent;
}
public NetComponent getNetComponent() {
return netComponent;
}
}
My NetModule (partially)
#Module
public class NetModule {
public NetModule() {
}
#Provides
#NetScope
BusWorker provideBusWorker(){
return new BusWorker();
}
}
NetScope
#Scope
#Retention(RetentionPolicy.RUNTIME)
public #interface NetScope {
}
My NetComponent
#NetScope
#Component(modules={AppModule.class, NetModule.class})
public interface NetComponent {
NetWorker netWorker();
DbWorker dbWorker();
LogWorker logWorker();
SharedPreferencesWorker sharedPreferences();
BusWorker BusWorker();
}
I modified the components, modules and the way they're being initialized in the Application class. This is the working code where the right message is received in the Application, Activity and fragment:
SchoolComponent
#SchoolScope
#Component(modules={SchoolModule.class})
public interface SchoolComponent {
void inject(MainActivity activity);
void inject(FragmentTest fragment);
void inject(App app);
School provideSchool();
}
NetComponent
#NetScope
#Component(modules={NetModule.class})
public interface NetComponent {
void inject(MainActivity activity);
void inject(FragmentTest fragment);
void inject(App app);
NetWorker provideNetWorker();
DbWorker provideDbWorker();
LogWorker provideLogWorker();
SharedPreferencesWorker provideSharedPreferences();
}
NetModule
#Module
public class NetModule {
#Provides
#NetScope
SharedPreferencesWorker provideSharedPreferences(){
return new SharedPreferencesWorker();
}
#Provides
#NetScope
NetWorker provideNetWorker(){
return new NetWorker();
}
#Provides
#NetScope
DbWorker provideDbWorker(){
return new DbWorker();
}
#Provides
#NetScope
LogWorker provideLogWorker(){
return new LogWorker();
}
#Provides
#NetScope
BusWorker provideBusWorker(){
return new BusWorker();
}
}
Application class
public class App extends Application {
private NetComponent netComponent;
private SchoolComponent schoolComponent;
#Inject
BusWorker busWorker;
#Inject
public App() {
}
#Override
public void onCreate() {
super.onCreate();
schoolComponent = DaggerSchoolComponent.create();
schoolComponent.inject(this);
netComponent = DaggerNetComponent.create();
netComponent.inject(this);
busWorker.register(this);
}
#Subscribe
public void recievedMessage(Message message) {
Log.d("Dagger", "recievedMessage App: " + message.getMessage());
}
public SchoolComponent getSchoolComponent() {
return schoolComponent;
}
public NetComponent getNetComponent() {
return netComponent;
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
#Inject
BusWorker busWorker;
#Inject
LogWorker logWorker;
#Inject
School school;
#Bind(R.id.name)
TextView name;
ActivityMainBinding binding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
ButterKnife.bind(this);
inject();
}
#Override
protected void onResume() {
super.onResume();
busWorker.register(this);
}
#Override
protected void onPause() {
super.onPause();
busWorker.unRegister(this);
}
#Subscribe
public void recievedMessage(Message message) {
logWorker.log("recievedMessage Activity: " + message.getMessage());
}
public void onClickButton(View view) {
switch (view.getId()) {
case R.id.button:
busWorker.post(new Message("blablabla"));
break;
default:
break;
}
}
void inject() {
((App) getApplication()).getNetComponent().inject(this);
((App) getApplication()).getSchoolComponent().inject(this);
}
}
Related
this is my mvp module
#Module
public class LoginModule {
#Provides
public LoginPresenterImpl providePresenter(LoginView loginView , LoginInteractor loginInteractor) {
return new LoginPresenterImpl(loginView,loginInteractor);
}
#Provides
public LoginView loginView(){
return new LoginActivity();
}
#Provides
public LoginInteractor loginInteractor(Repository repository){
return new LoginInteractorImpl(repository);
}
#Provides
public Repository provideRepository(APIInterfaces.LoginInterface loginInterface){
return new Repository(loginInterface,loginView());
}
#Provides
public LoginPresenter loginPresenter(APIInterfaces.LoginInterface loginInterface){
return providePresenter(loginView(),loginInteractor(provideRepository(loginInterface)));
}
}
this my login activity
{
ProgressHUD progressHUD;
private LinearLayout main_layout;
private boolean flag = false;
private EditText email_edt, password_edt;
private ImageView login_btn;
private TextView sign_up_tv, forget_password_tv;
#Inject
public LoginPresenter loginPresenter;
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
//getWindow().setStatusBarColor(Color.TRANSPARENT);
// flag = getIntent().getBooleanExtra("from_splash", false);
// loginPresenter = new LoginPresenterImpl(this,new LoginInteractorImpl());
MyApplication.getComponent().inject(this);
setControls();
} // onCreate()
#Override
protected void onDestroy() {
loginPresenter.onDestroy();
super.onDestroy();
}
private void setControls() {
main_layout = findViewById(R.id.main_login_layout);
email_edt = findViewById(R.id.edt_txt_email);
password_edt = findViewById(R.id.edt_txt_password);
sign_up_tv = findViewById(R.id.sign_up_txt);
forget_password_tv = findViewById(R.id.forget_password_txt);
login_btn = findViewById(R.id.login_btn);
login_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loginPresenter.validateEmailPassword(email_edt.getText().toString().trim(),password_edt.getText().toString().trim());
}
});
sign_up_tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
loginPresenter.openRegistrationPage();
}
});
forget_password_tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
if(flag)
Logging.Snackbar(main_layout, getString(R.string.check_internet_msg));
} // setControls()
#Override
public void showProgress() {
//progressHUD = ProgressHUD.show(LoginActivity.this, getString(R.string.loading_txt), false, null, null);
}
#Override
public void hideProgress() {
//progressHUD.dismiss();
}
#Override
public void passwordError(int x) {
switch (x)
{
case 0 :
password_edt.setError(getString(R.string.password_length_error_msg));
break;
case 1 :
password_edt.setError(getString(R.string.empty_field_error_msg));
break;
}
}
#Override
public void emailError(int y) {
switch (y)
{
case 0 :
email_edt.setError(getString(R.string.empty_field_error_msg));
break;
case 1 :
email_edt.setError(getString(R.string.invalid_email_error_msg));
break;
case 2 :
email_edt.setError(getString(R.string.invalid_email_error_msg));
break;
}
}
#Override
public void openRegistration() {
Intent intent = new Intent(LoginActivity.this, RegistrationActivity.class);
startActivity(intent);
finish();
}
#Override
public void forgetPassword() {
}
#Override
public void navigateToHome(Response<LoginResponse> response) {
if (response.body().getError() == 0 && response.body().getMessage().equalsIgnoreCase("Login Success"))
{
UserData userData = new UserData();
Intent intent = new Intent(this,MainPageActivity.class);
userData = response.body().getData();
intent.putExtra("UserData",userData);
startActivity(intent);
finish();
}
else
{
Logging.Toast(this,response.body().getMessage());
}
}
#Override
public void onError() {
Logging.Toast(this,"Check Your Internet Connection");
}
}
when i try to navigate to home activity LoginActivity.this is return null how to solve this.
this is the error that i get
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.content.ContextWrapper.getPackageName(ContextWrapper.java:141)
I Solved the problem by edit the MVP Module Like this
#Module
public class LoginModule {
private LoginView loginView;
public LoginModule(LoginView loginView) {
this.loginView = loginView;
}
#ActivityScope
#Provides
public LoginPresenterImpl providePresenter(LoginView loginView , LoginInteractor loginInteractor) {
return new LoginPresenterImpl(loginView,loginInteractor);
}
#ActivityScope
#Provides
public LoginView loginView(){
return loginView;
}
#ActivityScope
#Provides
public LoginInteractor loginInteractor(Repository repository){
return new LoginInteractorImpl(repository);
}
#ActivityScope
#Provides
public Repository provideRepository(APIInterfaces.LoginInterface loginInterface,APIInterfaces.getEventsInterface getEventsInterface){
return new Repository(loginInterface,getEventsInterface);
}
#ActivityScope
#Provides
public LoginPresenter loginPresenter(APIInterfaces.LoginInterface loginInterface,APIInterfaces.getEventsInterface getEventsInterface){
return providePresenter(loginView(),loginInteractor(provideRepository(loginInterface,getEventsInterface)));
}
}
and create activity scope for it
I have an activity with a viewpager of fragments filled with results of an api call:
ArtistFragment.java
public static ArtistFragment newInstance(String artistName, String imageUrl) {
ArtistFragment artistFragment = new ArtistFragment();
Bundle args = new Bundle();
args.putString(ARTIST_NAME, name);
args.putString(IMAGE_URL, imageUrl);
artistFragment.setArguments(args);
return artistFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BaseActivity activity = BaseActivity.get(getActivity());
AppComponent appComponent = activity.getAppComponent();
appComponent.inject(this);
imageUrl = getArguments().getString(IMAGE_URL);
title = getArguments().getString(TITLE);
}
MainActivity.java
public class MainActivity extends BaseActivity {
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
appComponent.inject(this);
}
#Override
public void onResume() {
super.onResume();
subscriptions.add(client.searchArtists("Impressionist")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<Artist>>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
Toast.makeText(getApplicationContext(),
e.getMessage(), Toast.LENGTH_LONG)
.show();
}
#Override
public void onNext(List<Artist> artists) {
ArtistPagerAdapter pagerAdapter = new
ArtistPagerAdapter(getSupportFragmentManager(),
artists);
viewPager.setAdapter(pagerAdapter);
}
}));
}
BaseActivity.java:
public class BaseActivity extends AppCompatActivity {
#Inject CompositeSubscription subscriptions;
AppComponent appComponent;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appComponent = MyApplication.get(this)
.getAppComponent();
appComponent.inject(this);
}
public static BaseActivity get(Context context) {
return (BaseActivity) context;
}
public AppComponent getAppComponent() {
return appComponent;
}
MyApplication.java
public class MyApplication extends Application {
private AppComponent appComponent;
public static MyApplication get(Context context) {
return (MyApplication) context.getApplicationContext();
}
#Override
public void onCreate() {
super.onCreate();
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.build();
}
public AppComponent getAppComponent() {
return appComponent;
}
}
ArtistPagerAdapter:
public class ArtistPagerAdapter extends FragmentStatePagerAdapter {
private List<Artist> results;
public ArtistPagerAdapter(FragmentManager fragmentManager,
List<Artist> results) {
super(fragmentManager);
this.results = results;
}
#Override
public int getCount() {
return results.size();
}
#Override
public Fragment getItem(int position) {
Artist artist = results.get(position);
String name = artist.getFullName();
String imageUrl = artist.getImageUrl();
return ArtistFragment.newInstance(name, imageUrl);
}
}
ApplicationComponent.java
#Component(modules = AppModule.class)
#Singleton
public interface AppComponent {
void inject(BaseActivity activity);
void inject(MainActivity activity);
void inject(ArtistFragment fragment);
}
I added log statements in the Activity and Fragment onCreate. If I rotate screen, why is the fragment's onCreate called prior to activity's onCreate?
put your code fragments in
onActivityCreated()
rather than
onCreate()
usually this happens when your memory is low and the activity is recycled.
I have an application (module + component) where
#Singleton
#Component(modules = AppModule.class)
public interface AppComponent {
void inject(App app);
Serializer getSerializer();
ListOfCallingLists getListOfCallingLists();
Context getContext();
App getApp();
}
And
#Module
public class AppModule {
private final App app;
public AppModule(App app) {
this.app = app;
}
#Provides
Serializer provideSerializer() {
return new BinarySerializer();
}
#Provides
Context provideContext() {
return app;
}
#Provides
App provideApp() {
return app;
}
}
And
#Singleton
public class ListOfCallingLists implements Serializable {
...
#Inject
public ListOfCallingLists(Context context,
Serializer serializer) {
this.serializer = serializer;
...
}
}
And App is the application, I registered it in manifest:
public class App extends Application {
private AppComponent appComponent;
public static App get(Context context) {
return (App) context.getApplicationContext();
}
#Override
public void onCreate() {
super.onCreate();
if (appComponent == null)
appComponent = DaggerAppComponent.builder()
.appModule(new AppModule(this))
.build();
appComponent.inject(this);
}
public AppComponent getComponent() {
return appComponent;
}
}
And finally the activity:
public class CallListsActivity extends AppCompatActivity {
#Inject
ListOfCallingLists list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}
#Override
public void onPostCreate(#Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// list here is null why?
}
}
In your AppComponent you need to add:
void inject(CallListsActivity callListActivity);
And in your CallListsActivity's onCreate() you need to tell how is your CallListsActivity injected.
For example, build your AppComponent and inject the activity, or you can use the new android injector: https://google.github.io/dagger/android.html
I want to add an activity as a dependency for one of my classes
class ViewHandler{
#inject public ViewHandler(Myactivity myactivity){
this.activity = myactivity;
}
}
how can I do this without being obstructed by the Activity life cycle
You need to use subscoped components with modules for this.
#Singleton
#Component(modules={SomethingModule.class})
public interface ApplicationComponent {
Something something();
}
#Module
public class SomethingModule {
#Provides
#Singleton
public Something something() {
return new Something();
}
}
#ActivityScope
#Component(dependencies={ApplicationComponent.class}, modules={MyActivityModule.class})
public interface MyActivityComponent extends ApplicationComponent {
ViewHandler viewHandler();
void inject(Myactivity myActivity);
}
#Module
public class MyActivityModule {
private Myactivity myActivity;
public MyActivityModule(Myactivity myActivity) {
this.myActivity = myActivity;
}
#Provides
public Myactivity myActivity() {
return myActivity;
}
#Provides
#ActivityScope
public ViewHandler viewHandler(Myactivity myActivity) {
return new ViewHandler(myActivity);
}
}
public class CustomApplication extends Application {
ApplicationComponent applicationComponent;
#Override
public void onCreate() {
super.onCreate();
applicationComponent = DaggerApplicationComponent.create();
}
public ApplicationComponent getApplicationComponent() {
return applicationComponent;
}
}
public class Myactivity extends AppCompatActivity {
MyActivityComponent myActivityComponent;
#Inject
ViewHandler viewHandler;
#Override
public void onCreate(Bundle saveInstanceState) {
super.onCreate(saveInstanceState);
CustomApplication customApp = (CustomApplication)getApplicationContext();
this.myActivityComponent = DaggerMyActivityComponent.builder()
.applicationComponent(customApp.getApplicationComponent())
.myActivityModule(new MyActivityModule(this))
.build(); //preserve the state of your dependencies in onSaveInstanceState();
myActivityComponent.inject(this);
}
}
EDIT: Another option is #Subcomponent annotation
#Singleton
#Component(modules={SomethingModule.class})
public interface ApplicationComponent {
Something something();
MyActivityComponent newMyActivityComponent(MyActivityModule myActivityModule);
}
#ActivityScope
#Subcomponent(modules={MyActivityModule.class})
public interface MyActivityComponent {
ViewHandler viewHandler();
void inject(Myactivity myActivity);
}
public class Myactivity extends AppCompatActivity {
MyActivityComponent myActivityComponent;
#Inject
ViewHandler viewHandler;
#Override
public void onCreate(Bundle saveInstanceState) {
super.onCreate(saveInstanceState);
CustomApplication customApp = (CustomApplication)getApplicationContext();
this.myActivityComponent = customApp.getApplicationComponent()
.newMyActivityComponent(new MyActivityModule(this));
myActivityComponent.inject(this);
}
}
Here's my code, which I based on some old tutorial found on the internet. There really should be some examples on the main site of Dagger 2, I found it really difficult to understand how to implement all this.
It's really a lot of work to get such a simple app to run. I have two questions:
Do I have to call DaggerLoggerComponent in every class I want to get some components like my Logger class?
Also how can I make the scope of the Logger class a singleton? Right now every button click creates a new logger instance.
Probably I dont understand some underlying concepts, I've only used dependency injection in Spring before and all of this seems strange to me.
public class MainActivity extends AppCompatActivity {
private Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init(){
button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LoggerComponent component = DaggerLoggerComponent.builder().loggerModule(new LoggerModule()).build();
component.getLogger().log("Hello!",MainActivity.this);
}
});
}
}
public class Logger {
private static int i = 0;
public Logger(){
i++;
}
public static int getI() {
return i;
}
public void log(String text, Context context){
Toast.makeText(context,text+" "+i,Toast.LENGTH_SHORT).show();
}
}
#Singleton
#Component(modules={LoggerModule.class})
public interface LoggerComponent {
Logger getLogger();
}
#Module
public class LoggerModule {
#Provides
#Singleton
Logger provideLogger(){
return new Logger();
}
}
The answer is
public class MainActivity extends AppCompatActivity {
#OnClick(R.id.button) //ButterKnife
public void onClickButton() {
logger.log("Hello!");
}
#Inject
Logger logger;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Injector.INSTANCE.getApplicationComponent().inject(this);
ButterKnife.bind(this);
}
#Override
protected void onDestroy() {
ButterKnife.unbind(this);
super.onDestroy();
}
}
public class Logger {
private static int i = 0;
private CustomApplication customApplication;
public Logger(CustomApplication application) {
this.customApplication = application;
i++;
}
public static int getI() {
return i;
}
public void log(String text){
Toast.makeText(customApplication, text + " " + i,Toast.LENGTH_SHORT).show();
}
}
public interface LoggerComponent {
Logger logger();
}
#Module
public class ApplicationModule {
private CustomApplication customApplication;
public ApplicationModule(CustomApplication customApplication) {
this.customApplication = customApplication;
}
#Provides
public CustomApplication customApplication() {
return customApplication;
}
}
#Module
public class LoggerModule {
#Provides
#Singleton
Logger provideLogger(){
return new Logger();
}
}
#Singleton
#Component(modules={LoggerModule.class, ApplicationModule.class})
public interface ApplicationComponent extends LoggerComponent {
CustomApplication customApplication();
void inject(MainActivity mainActivity);
}
public class CustomApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
Injector.INSTANCE.initializeApplicationComponent(this);
}
}
public enum Injector {
INSTANCE;
private ApplicationComponent applicationComponent;
public ApplicationComponent getApplicationComponent() {
return applicationComponent;
}
void initializeApplicationComponent(CustomApplication customApplication) {
this.applicationComponent = DaggerApplicationComponent.builder()
.applicationModule(new ApplicationModule(customApplication))
.build();
}
}
This is currently our Dagger2 architecture.
EDIT: This is from our actual code for Retrofit stuff from our application we're making:
public interface RecordingService {
ScheduledRecordsXML getScheduledRecords(long userId)
throws ServerErrorException;
}
public class RecordingServiceImpl
implements RecordingService {
private static final String TAG = RecordingServiceImpl.class.getSimpleName();
private RetrofitRecordingService retrofitRecordingService;
public RecordingServiceImpl(RetrofitRecordingService retrofitRecordingService) {
this.retrofitRecordingService = retrofitRecordingService;
}
#Override
public ScheduledRecordsXML getScheduledRecords(long userId)
throws ServerErrorException {
try {
return retrofitRecordingService.getScheduledPrograms(String.valueOf(userId));
} catch(RetrofitError retrofitError) {
Log.e(TAG, "Error occurred in downloading XML file.", retrofitError);
throw new ServerErrorException(retrofitError);
}
}
}
#Module
public class NetworkClientModule {
#Provides
#Singleton
public OkHttpClient okHttpClient() {
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.interceptors().add(new HeaderInterceptor());
return okHttpClient;
}
}
#Module(includes = {NetworkClientModule.class})
public class ServiceModule {
#Provides
#Singleton
public RecordingService recordingService(OkHttpClient okHttpClient, Persister persister, AppConfig appConfig) {
return new RecordingServiceImpl(
new RestAdapter.Builder().setEndpoint(appConfig.getServerEndpoint())
.setConverter(new SimpleXMLConverter(persister))
.setClient(new OkClient(okHttpClient))
.setLogLevel(RestAdapter.LogLevel.NONE)
.build()
.create(RetrofitRecordingService.class));
}
//...
}
public interface RetrofitRecordingService {
#GET("/getScheduledPrograms")
ScheduledRecordsXML getScheduledPrograms(#Query("UserID") String userId);
}
public interface ServiceComponent {
RecordingService RecordingService();
//...
}
public interface AppDomainComponent
extends InteractorComponent, ServiceComponent, ManagerComponent, ParserComponent {
}
#Singleton
#Component(modules = {
//...
InteractorModule.class,
ManagerModule.class,
ServiceModule.class,
ParserModule.class
//...
})
public interface ApplicationComponent
extends AppContextComponent, AppDataComponent, AppDomainComponent, AppUtilsComponent, AppPresentationComponent {
void inject(DashboardActivity dashboardActivity);
//...
}
Do I have to call DaggerLoggerComponent in every class I want to get some components like my Logger class?
Yes for all classes that created by the system like Application, Activity and Service. but for you own classes, you don't need that. just annotate you constructor with #inject and dagger will provide your dependencies.
Also how can I make the scope of the Logger class a singleton? Right
now every button click creates a new logger instance.
Your setup for singleton is correct. but you have to initialize the component one time after the activity is created (onCreate) in order to let dagger to inject all fields. Also you can utilize lazy injection feature if you don't need the Logger object right away.
#Inject
Logger logger;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LoggerComponent component = DaggerLoggerComponent.builder().loggerModule(new LoggerModule()).build();
component.inject(this);
init();
}
Then you can access your object without take the reference from the component:
private void init(){
button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
logger.log("Hello!",MainActivity.this);
}
});
}
In summary:
You have to initialize the component in all classes that use field injections.
UPDATE:
To do the actual injection, you have to declare inject() method into your component and dagger will automatically implement it. This method will take care of provide any object annotated with #Inject.