/**
* Copyright (C) 2013 - 2015 the enviroCar community
*
* This file is part of the enviroCar app.
*
* The enviroCar app is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The enviroCar app is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with the enviroCar app. If not, see http://www.gnu.org/licenses/.
*/
package org.envirocar.core.injection;
import android.app.Activity;
import android.support.v4.app.Fragment;
import android.util.Log;
import com.google.common.base.Preconditions;
import com.squareup.otto.Bus;
import java.lang.reflect.Field;
import java.util.List;
import javax.inject.Inject;
import dagger.ObjectGraph;
/**
* @author dewall
*/
public abstract class BaseInjectorFragment extends Fragment implements Injector,
InjectionModuleProvider {
private static final String TAG = BaseInjectorFragment.class.getSimpleName();
private static final Field mChildFragmentManagerFieldOfFragment;
static {
Field f = null;
try {
f = Fragment.class.getDeclaredField("mChildFragmentManager");
f.setAccessible(true);
} catch (NoSuchFieldException e) {
Log.e(TAG, "Error while getting the declared mChildFragmentManager field", e);
}
mChildFragmentManagerFieldOfFragment = f;
}
/**
* The event bus allows publish-subscribe-style communication. It dispatches
* events to subscribed listeners, and provides ways for listeners to
* register themselves.
*/
@Inject
protected Bus mBus;
/**
* A graph of objects linked by their dependencies. This class is used for
* dependency injection. (see Dagger library)
*/
private ObjectGraph mObjectGraph;
/**
* Flag that indicates that the fragment is already attached and the object
* graph was initialized.
*/
private boolean mAlreadyAttached;
private boolean mIsRegistered;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Check if it is the first time where this fragment was attached to the
// activity. If false, the ObjectGraph will be extended by fragment
// specific modules and the dependencies will be injected.
if (!mAlreadyAttached || mObjectGraph == null) {
ObjectGraph objectGraph = ((Injector) getActivity()).getObjectGraph();
List<Object> moduleList = getInjectionModules();
if (moduleList != null) {
objectGraph = objectGraph.plus(moduleList.toArray());
}
this.mObjectGraph = objectGraph;
// Inject ourselves.
injectObjects(this);
mAlreadyAttached = true;
Preconditions.checkState(mBus != null, "Bus has to be injected before "
+ "registering the providers and subscribers.");
}
if(!mIsRegistered){
// Register ourselves on the bus
mBus.register(this);
mIsRegistered = true;
}
}
@Override
public void onDetach() {
Log.d(TAG, "onDetach() fragment");
super.onDetach();
try {
mChildFragmentManagerFieldOfFragment.set(this, null);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if(mIsRegistered) {
mBus.unregister(this);
mIsRegistered = false;
}
}
/**
* Gets the object graph of the implemented class.
*
* @return the object graph
*/
@Override
public final ObjectGraph getObjectGraph() {
return mObjectGraph;
}
/**
* Injects a target object using this object's object graph.
*
* @param instance the target object
*/
@Override
public void injectObjects(Object instance) {
Preconditions.checkState(mObjectGraph != null,
"ObjectGraph must be initialized before injecting objects.");
mObjectGraph.inject(instance);
Log.d(TAG, "Objects successfully injected into "
+ instance.getClass().getSimpleName());
}
/**
* Returns a list of modules to be added to the ObjectGraph. Originally this
* function returns null, but can be extended by subclasses by own modules.
*
* @return a list of modules
*/
@Override
public List<Object> getInjectionModules() {
return null;
}
}