@Override protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { //Log.d("BlackMirror", "BlackMirror.loadClass - " + name + " " + resolve); ClassRequest request = ClassRequest.builder().name(name).build(); return new InterceptorChain(interceptors, 0, request).proceed(request).clazz(); }
@Override public ClassResult intercept(Chain chain) throws ClassNotFoundException { if (chain.request().name().equals("java.util.List")) { ClassResult result = chain.proceed(chain.request()); return result.toBuilder().clazz(fakeClass(result.clazz())).build(); } return chain.proceed(chain.request()); }
@SuppressWarnings("ConstantConditions") @Override public boolean onCreate() { try { Log.d("BLAH", "InitProvider.static initializer - "); BlackMirror.install(getContext(), interceptors(getContext())); Log.d("BLAH", "InitProvider.static initializer - Success"); } catch (Exception e) { e.printStackTrace(); } return true; }
public static ClassLoader loadClassLoader(Context context) { try { ByteBuffer[] buffers = new ByteBuffer[1]; // Read the dex file into memory as a bytebuffer InputStream is = context.getAssets().open("helloimpl.dex"); buffers[0] = ByteBufferUtil.loadBuffer(is); return ByteBufferUtil.createClassLoaderFromDexFiles(context.getClassLoader(), buffers); } catch (Exception e) { throw new RuntimeException(e); } }
@SuppressWarnings("ConstantConditions") @Override public boolean onCreate() { try { Log.d("BLAH", "InitProvider.static initializer - "); BlackMirror.install(getContext()); Log.d("BLAH", "InitProvider.static initializer - Success"); } catch (Exception e) { e.printStackTrace(); } return true; }
@Override public ClassResult proceed(ClassRequest request) throws ClassNotFoundException { if (index >= interceptors.size()) { throw new AssertionError("no interceptors added to the chain"); } // Call the next interceptor in the chain. InterceptorChain next = new InterceptorChain(interceptors, index + 1, request); Interceptor interceptor = interceptors.get(index); ClassResult result = interceptor.intercept(next); // Confirm that the intercepted response isn't null. if (result == null) { throw new NullPointerException("interceptor " + interceptor + " returned null"); } return result; }
@Override public void onCreate() { super.onCreate(); try { Timber.plant(new Timber.DebugTree()); // Example of deferred classloading in application. // Can use BlackMirror.getInstance() directly or getClassLoader(). // You're fine after this though Class<?> clazz = BlackMirror.getInstance().loadClass("io.sweers.blackmirror.app.AppDelegate"); Method method = clazz.getDeclaredMethod("onCreate"); method.setAccessible(true); method.invoke(null); } catch (Exception e) { throw new RuntimeException(e); } } }
public static Builder builder() { return new Builder(); }
public Builder toBuilder() { return new Builder(this); }
public ClassRequest build() { if (name == null) { throw new IllegalStateException("name == null"); } return new ClassRequest(this); } }
private static synchronized void init(ClassLoader delegate, Context context, List<? extends Interceptor> interceptors) { instance = new BlackMirror(delegate, context.getApplicationInfo().sourceDir, interceptors); }
public ClassResult build() { if (name == null) { throw new IllegalStateException("name == null"); } if (clazz != null && !name.equals(clazz.getName())) { throw new IllegalStateException("name (" + name + ") " + "must be the class's fully qualified name (" + clazz.getName() + ")"); } return new ClassResult(this); } }
@Override public ClassResult intercept(Chain chain) throws ClassNotFoundException { long start = SystemClock.elapsedRealtimeNanos(); ClassResult result = chain.proceed(chain.request()); Timber.tag("BlackMirror") .d("Loading \"%s\", took %dns", chain.request().name(), SystemClock.elapsedRealtimeNanos() - start); return result; } }
public static ClassLoader loadClassLoader(Context context) { try { ByteBuffer[] buffers = new ByteBuffer[1]; // Read the dex file into memory as a bytebuffer InputStream is = context.getResources().openRawResource(R.raw.helloimpl); buffers[0] = ByteBufferUtil.loadBuffer(is); return ByteBufferUtil.createClassLoaderFromDexFiles(context.getClassLoader(), buffers); } catch (Exception e) { throw new RuntimeException(e); } }
public Builder toBuilder() { return new Builder(this); }
public static Builder builder() { return new Builder(); }