public static DefaultRoboModule newDefaultRoboModule(final Application application) { return new DefaultRoboModule(application, new ContextScope(application)); }
@Inject public ContextScope(Application application) { this.application = application; // Add the context to the scope for key Context, Activity, etc. Class<?> c = application.getClass(); do { applicationScopedObjects.put(Key.get(c), application); c = c.getSuperclass(); } while (c != Object.class); enter(application, applicationScopedObjects); }
public void exit(Context context) { //System.out.println("exiting scope of : " + context); final Stack<ScopedObjects> stack = getContextStack(); ScopedObjects currentScopedObject = stack.peek(); if (currentScopedObject.getContextWeakReference().get() == context) { currentScopedObject.setEnterCount(currentScopedObject.getEnterCount() - 1); } if (currentScopedObject.getEnterCount() >= 0 && currentScopedObject.getContextWeakReference().get() == context) { //System.out.println("fast exit"); return; } final Context c = stack.pop().getContextWeakReference().get(); if (c != null && c != context) { throw new IllegalArgumentException(String.format("Scope for %s must be opened before it can be closed", context)); } }
/** * You MUST perform any injector operations inside a synchronized(ContextScope.class) block that starts with * scope.enter(context) if working in a multithreaded environment * * @param context the context to enter * @see ContextScope * @see ContextScopedRoboInjector * @see ContextScopedProvider */ public void enter(Context context, Map<Key<?>, Object> scopedObjects) { //System.out.println("entering scope of : " + context); final Stack<ScopedObjects> stack = getContextStack(); if (!stack.isEmpty()) { ScopedObjects currentScopedObject = stack.peek(); if (currentScopedObject.getContextWeakReference().get() == context) { currentScopedObject.setEnterCount(currentScopedObject.getEnterCount() + 1); //System.out.println("fast enter"); return; } } // Mark this thread as for this context stack.push(new ScopedObjects(new WeakReference<Context>(context), scopedObjects)); }
@Override public <T> MembersInjector<T> getMembersInjector(TypeLiteral<T> typeLiteral) { //System.out.println("in getMembersInjector"); synchronized (ContextScope.class) { scope.enter(context, scopedObjects); try { return delegate.getMembersInjector(typeLiteral); } finally { scope.exit(context); } } }