Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ buildscript {


android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
compileSdkVersion 25
buildToolsVersion "25.0.2"

defaultConfig {
applicationId "me.martinez.sergio.daggertwobasearchitecture"
minSdkVersion 15
targetSdkVersion 21
targetSdkVersion 25
versionCode 1
versionName "1.0"
}
Expand All @@ -48,8 +48,8 @@ android {

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
apt 'com.google.dagger:dagger-compiler:2.0'
compile 'com.google.dagger:dagger:2.0'
compile 'com.android.support:appcompat-v7:25.1.0'
compile 'com.google.dagger:dagger:2.7'
apt 'com.google.dagger:dagger-compiler:2.7'
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read below and Try to change it by
annotationProcessor 'com.google.dagger:dagger-compiler:2.7'

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

provided 'org.glassfish:javax.annotation:10.0-b28'
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;

import java.util.List;

import javax.inject.Inject;
import me.martinez.sergio.daggertwobasearchitecture.di.components.DaggerSectionComponentMain;

import me.martinez.sergio.daggertwobasearchitecture.di.components.SectionComponent;
import me.martinez.sergio.daggertwobasearchitecture.di.injectableelements.base.App;
import me.martinez.sergio.daggertwobasearchitecture.di.injectableelements.base.BaseFragment;
import me.martinez.sergio.daggertwobasearchitecture.di.injectableelements.base.BaseInjectionActivity;
import me.martinez.sergio.daggertwobasearchitecture.di.modules.ActivityModule;
import me.martinez.sergio.daggertwobasearchitecture.fragments.MainFragment;
import me.martinez.sergio.daggertwobasearchitecture.R;
import me.martinez.sergio.daggertwobasearchitecture.fragments.sections.testsection.firststep.FirstFragment;
Expand All @@ -38,149 +41,146 @@
import me.martinez.sergio.daggertwobasearchitecture.utils.Log4Me;

public class MainActivity extends BaseInjectionActivity<MainActivityComponent> implements
View.OnClickListener {

private Button buttonClearFragments;
private Button buttonAddFirstFragment;
private Button buttonAddSecondFragment;

@Inject A a;
@Inject B b;
@Inject Log4Me logger;
@Inject List<String> diInjectionHistory;

private Object sectionComponent;

@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initButtons();
initFragment();
initOnClickListeners();
testDI();
}

private void initButtons() {
buttonAddSecondFragment = (Button) findViewById(R.id.buttonAddFirstFragment);
buttonAddFirstFragment = (Button) findViewById(R.id.buttonAddSecondFragment);
buttonClearFragments = (Button) findViewById(R.id.buttonClearFragments);
}

private void initOnClickListeners() {
buttonAddSecondFragment.setOnClickListener(this);
buttonAddFirstFragment.setOnClickListener(this);
buttonClearFragments.setOnClickListener(this);
}

//region Init methods
private void initFragment() {
FragmentManager fragmentManager = getSupportFragmentManager();
MainFragment mainFragment = new MainFragment();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.fragmentContainer, mainFragment);
ft.commit();
}

private void addFragment(BaseFragment baseFragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.add(R.id.fragmentContainer, baseFragment).
addToBackStack(baseFragment.getClass().getSimpleName()).commit();
}

private void clearFragmentStack() {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStack(FirstFragment.class.getSimpleName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
}

//endregion

//region Android AutoGenerated methods

@Override public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

@Override public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
View.OnClickListener {

private Button buttonClearFragments;
private Button buttonAddFirstFragment;
private Button buttonAddSecondFragment;
private SectionComponent sectionComponent;

@Inject
A a;
@Inject
B b;
@Inject
Log4Me logger;
@Inject
List<String> diInjectionHistory;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initButtons();
initFragment();
initOnClickListeners();
testDI();
}

return super.onOptionsItemSelected(item);
}
private void initButtons() {
buttonAddSecondFragment = (Button) findViewById(R.id.buttonAddFirstFragment);
buttonAddFirstFragment = (Button) findViewById(R.id.buttonAddSecondFragment);
buttonClearFragments = (Button) findViewById(R.id.buttonClearFragments);
}

//endregion
private void initOnClickListeners() {
buttonAddSecondFragment.setOnClickListener(this);
buttonAddFirstFragment.setOnClickListener(this);
buttonClearFragments.setOnClickListener(this);
}

//region Test DI stuff
private void testDI() {
//region Init methods
private void initFragment() {
FragmentManager fragmentManager = getSupportFragmentManager();
MainFragment mainFragment = new MainFragment();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.fragmentContainer, mainFragment);
ft.commit();
}

diInjectionHistory.add(MainActivity.class.getName());
diInjectionHistory.add(logger.toString());
diInjectionHistory.add(a.toString());
diInjectionHistory.add(b.toString());
private void addFragment(BaseFragment baseFragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.add(R.id.fragmentContainer, baseFragment).
addToBackStack(baseFragment.getClass().getSimpleName()).commit();
}

}
//endregion
private void clearFragmentStack() {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStack(FirstFragment.class.getSimpleName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
}

//region dependency injection Methods
//endregion

@Override protected void initDI() {
activityComponent = DaggerMainActivityComponent.builder().appComponent(getAppComponent())
.activityModule(new ActivityModule(this))
.mainActivityModule(new MainActivityModule(this)).build();
activityComponent.injectActivity(this);
}
//region Android AutoGenerated methods

//region Section Stuff
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

private void initSectionComponent() {
sectionComponent =
DaggerSectionComponentMain.builder().mainActivityComponent(activityComponent).build();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();

private void clearSectionComponent(){
sectionComponent = null;
}
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}

@Override
public Object getActivityComponent() {
if (sectionComponent!=null){
return sectionComponent;
}else{
return activityComponent;
return super.onOptionsItemSelected(item);
}
}

//endregion
//endregion

//endregion
//region Test DI stuff
private void testDI() {

@Override public void onClick(View v) {
switch (v.getId()){
case R.id.buttonAddFirstFragment:
initSectionComponent();
addFragment(new FirstFragment());
break;
case R.id.buttonAddSecondFragment:
addFragment(new SecondFragment());
break;
case R.id.buttonClearFragments:
clearSectionComponent();
diInjectionHistory.add(MainActivity.class.getName());
diInjectionHistory.add(logger.toString());
diInjectionHistory.add(a.toString());
diInjectionHistory.add(b.toString());

}
//endregion

//region dependency injection Methods

@Override
protected MainActivityComponent initDI() {
MainActivityComponent activityComponent = ((App) getApplication()).getComponentProxy().getMainActivityComponent(this);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I realized that you're delegating MainActivityComponent creation out of the activity. I guess you've implemented this method injection in order to be able of taking control of the creator by using the right implementation of yourComponentProxy interface. I like it! 👍

activityComponent.injectActivity(this);
return activityComponent;
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.buttonAddFirstFragment:
addSection();
break;
case R.id.buttonAddSecondFragment:
addFragment(new SecondFragment());
break;
case R.id.buttonClearFragments:
clearSection();
break;
default:
break;
}
}

private void clearSection() {
clearFragmentStack();
break;
default:
break;
sectionComponent = null;
}
}

private void addSection() {
initSection();
addFragment(new FirstFragment());
}

private void initSection() {
sectionComponent = ((App)getApplication()).getComponentProxy().getSectionComponent(this);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, delegate into a new piece the creation of component, you're like this hiding the dependencies you have, it is a great idea.

}


public SectionComponent getSectionComponent() {
return sectionComponent;
}
}
38 changes: 2 additions & 36 deletions ...n/java/me/martinez/sergio/daggertwobasearchitecture/activities/MainActivityComponent.java
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,39 +1,5 @@
/*
* Copyright (C) 2015 Sergio Martinez Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package me.martinez.sergio.daggertwobasearchitecture.activities;

import dagger.Component;
import java.util.List;
import me.martinez.sergio.daggertwobasearchitecture.di.components.AppComponent;
import me.martinez.sergio.daggertwobasearchitecture.di.modules.ActivityModule;
import me.martinez.sergio.daggertwobasearchitecture.di.anotations.scopes.PerActivity;
import me.martinez.sergio.daggertwobasearchitecture.fragments.MainFragment;
import me.martinez.sergio.daggertwobasearchitecture.test.A;
import me.martinez.sergio.daggertwobasearchitecture.utils.Log4Me;

/**
* Created by Sergio Martinez Rodriguez
* Date 15/7/15.
*/
@PerActivity
@Component(dependencies = AppComponent.class, modules = {ActivityModule.class, MainActivityModule.class})
public interface MainActivityComponent extends MainFragment.Pluser{
void injectActivity(MainActivity mainActivity);
A provideA();
List<String> provideDiInjectionHistory();
Log4Me provideLog4Me();
public interface MainActivityComponent {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This interface is the one you use in your proxy facade and clients like MainActivity. And is the one that your implementation strategies "Test" and "prod" MUST implement in order to be swapped at "ComponentProxy" implementation point.

void injectActivity(MainActivity mainActivity);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (C) 2015 Sergio Martinez Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package me.martinez.sergio.daggertwobasearchitecture.activities;

import javax.inject.Provider;

import dagger.Subcomponent;
import me.martinez.sergio.daggertwobasearchitecture.di.components.SectionComponent;
import me.martinez.sergio.daggertwobasearchitecture.di.modules.ActivityModule;
import me.martinez.sergio.daggertwobasearchitecture.di.anotations.scopes.PerActivity;
import me.martinez.sergio.daggertwobasearchitecture.fragments.MainFragmentComponent;

@PerActivity
@Subcomponent(modules = {ActivityModule.class, MainActivityModule.class})
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this @Subcomponent annotation I've realized that you have changed Appcomponent-MainActivityComponent relationship from a Component relationship into a subcomponent one. I wonder If that is strictly necessary. As far as I know it could keep as Component relationship. Did you commit this change because of any reason I'm misunderstanding maybe?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean that before the relationship was depends and now is a subcomponent? I decided to migrate the whole thing to the new API, perhaps I misunderstood that part and not everything needs to be a subcomponent.
For what I know, having it as sub-component is not the only way to make it get the corresponding bindings, but it would make sense if you want to define some sort of hierarchy. I think for Application-> Activity would make sense.

public interface MainActivityComponentProd extends MainActivityComponent {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, is there point where you really have your dependencies and you can provide another MainActivityComponent implementation like MainActivityComponentProd using your mock dependencies. That's part of the magic. isn't it?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, abstraction layers everywhere, I think it's improvable, in the way that you may not need to expose the subcomponent builder in this interface, which would make the interface kind of useless whatsoever.

Provider<MainFragmentComponent.Builder> mainFragmentComponentBuilderProvider();
Provider<SectionComponent.Builder> sectionComponentProdBuilderProvider();
@Subcomponent.Builder
interface Builder {
Builder mainActivityComponentProd(MainActivityModule mainActivityModule);
Builder activityModule(ActivityModule activityModule);
MainActivityComponentProd build();
}
}
Loading