Introducing nucleus
This commit is contained in:
parent
68f1102c40
commit
235ed36fbe
3 changed files with 113 additions and 0 deletions
|
@ -48,6 +48,7 @@ dependencies {
|
||||||
final HAMCREST_VERSION = '1.3'
|
final HAMCREST_VERSION = '1.3'
|
||||||
final MOCKITO_VERSION = '1.10.19'
|
final MOCKITO_VERSION = '1.10.19'
|
||||||
final STORIO_VERSION = '1.4.0'
|
final STORIO_VERSION = '1.4.0'
|
||||||
|
final NUCLEUS_VERSION = '2.0.1'
|
||||||
|
|
||||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
|
||||||
|
@ -65,6 +66,9 @@ dependencies {
|
||||||
compile 'io.reactivex:rxandroid:1.0.1'
|
compile 'io.reactivex:rxandroid:1.0.1'
|
||||||
compile "com.pushtorefresh.storio:sqlite:$STORIO_VERSION"
|
compile "com.pushtorefresh.storio:sqlite:$STORIO_VERSION"
|
||||||
compile "com.pushtorefresh.storio:sqlite-annotations:$STORIO_VERSION"
|
compile "com.pushtorefresh.storio:sqlite-annotations:$STORIO_VERSION"
|
||||||
|
compile "info.android15.nucleus:nucleus:$NUCLEUS_VERSION"
|
||||||
|
compile "info.android15.nucleus:nucleus-support-v4:$NUCLEUS_VERSION"
|
||||||
|
compile "info.android15.nucleus:nucleus-support-v7:$NUCLEUS_VERSION"
|
||||||
compile 'de.greenrobot:eventbus:2.4.0'
|
compile 'de.greenrobot:eventbus:2.4.0'
|
||||||
compile 'com.github.bumptech.glide:glide:3.6.1'
|
compile 'com.github.bumptech.glide:glide:3.6.1'
|
||||||
compile 'com.jakewharton:butterknife:7.0.1'
|
compile 'com.jakewharton:butterknife:7.0.1'
|
||||||
|
|
|
@ -17,6 +17,7 @@ import timber.log.Timber;
|
||||||
public class App extends Application {
|
public class App extends Application {
|
||||||
|
|
||||||
AppComponent mApplicationComponent;
|
AppComponent mApplicationComponent;
|
||||||
|
ComponentReflectionInjector<AppComponent> mComponentInjector;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
|
@ -27,6 +28,9 @@ public class App extends Application {
|
||||||
.appModule(new AppModule(this))
|
.appModule(new AppModule(this))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
mComponentInjector =
|
||||||
|
new ComponentReflectionInjector<>(AppComponent.class, mApplicationComponent);
|
||||||
|
|
||||||
//ACRA.init(this);
|
//ACRA.init(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +42,14 @@ public class App extends Application {
|
||||||
return mApplicationComponent;
|
return mApplicationComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ComponentReflectionInjector<AppComponent> getComponentReflection() {
|
||||||
|
return mComponentInjector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ComponentReflectionInjector<AppComponent> getComponentReflection(Context context) {
|
||||||
|
return get(context).getComponentReflection();
|
||||||
|
}
|
||||||
|
|
||||||
public static AppComponent getComponent(Context context) {
|
public static AppComponent getComponent(Context context) {
|
||||||
return get(context).getComponent();
|
return get(context).getComponent();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
package eu.kanade.mangafeed;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class allows to inject into objects through a base class,
|
||||||
|
* so we don't have to repeat injection code everywhere.
|
||||||
|
*
|
||||||
|
* The performance drawback is about 0.013 ms per injection on a very slow device,
|
||||||
|
* which is negligible in most cases.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* <pre>{@code
|
||||||
|
* Component {
|
||||||
|
* void inject(B b);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* class A {
|
||||||
|
* void onCreate() {
|
||||||
|
* componentReflectionInjector.inject(this);
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* class B extends A {
|
||||||
|
* @Inject MyDependency dependency;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* new B().onCreate() // dependency will be injected at this point
|
||||||
|
*
|
||||||
|
* class C extends B {
|
||||||
|
*
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* new C().onCreate() // dependency will be injected at this point as well
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @param <T> a type of dagger 2 component.
|
||||||
|
*/
|
||||||
|
public final class ComponentReflectionInjector<T> {
|
||||||
|
|
||||||
|
private final Class<T> componentClass;
|
||||||
|
private final T component;
|
||||||
|
private final HashMap<Class<?>, Method> methods;
|
||||||
|
|
||||||
|
public ComponentReflectionInjector(Class<T> componentClass, T component) {
|
||||||
|
this.componentClass = componentClass;
|
||||||
|
this.component = component;
|
||||||
|
this.methods = getMethods(componentClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getComponent() {
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void inject(Object target) {
|
||||||
|
|
||||||
|
Class targetClass = target.getClass();
|
||||||
|
Method method = methods.get(targetClass);
|
||||||
|
while (method == null && targetClass != null) {
|
||||||
|
targetClass = targetClass.getSuperclass();
|
||||||
|
method = methods.get(targetClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method == null)
|
||||||
|
throw new RuntimeException(String.format("No %s injecting method exists in %s component", target.getClass(), componentClass));
|
||||||
|
|
||||||
|
try {
|
||||||
|
method.invoke(component, target);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ConcurrentHashMap<Class<?>, HashMap<Class<?>, Method>> cache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private static HashMap<Class<?>, Method> getMethods(Class componentClass) {
|
||||||
|
HashMap<Class<?>, Method> methods = cache.get(componentClass);
|
||||||
|
if (methods == null) {
|
||||||
|
synchronized (cache) {
|
||||||
|
methods = cache.get(componentClass);
|
||||||
|
if (methods == null) {
|
||||||
|
methods = new HashMap<>();
|
||||||
|
for (Method method : componentClass.getMethods()) {
|
||||||
|
Class<?>[] params = method.getParameterTypes();
|
||||||
|
if (params.length == 1)
|
||||||
|
methods.put(params[0], method);
|
||||||
|
}
|
||||||
|
cache.put(componentClass, methods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return methods;
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue