我如何使用隐藏的课程?
我可以通过反射使用隐藏类,隐藏方法或隐藏字段。 但在我的情况下,我必须扩展一个隐藏的类并覆盖非私有方法。
我有一个解决方案 Android: Extending a hidden class that is obtained through reflection ,它使用一个虚拟类来动态替换它。
我尝试了,但不幸的是我得到了java.lang.IllegalAccessError
我创建了一个虚拟模块和一个虚拟类android.app.ContextImpl$ServiceFetcher
,
然后在主模块中创建了一个类来扩展它。
另外,我通过provide 'xxxx'
编译了虚拟模块
当我加载类时,将抛出错误。
有人可以帮帮我吗?
以下是代码:
虚拟课
package android.app;
import android.content.Context;
import java.util.ArrayList;
class ContextImpl {
// The system service cache for the system services that are
// cached per-ContextImpl. Package-scoped to avoid accessor
// methods.
final ArrayList<Object> mServiceCache = new ArrayList<Object>();
private static int sNextPerContextServiceCacheIndex = 0;
/*package*/ static class ServiceFetcher {
int mContextCacheIndex = -1;
/**
* Main entrypoint; only override if you don't need caching.
*/
public Object getService(ContextImpl ctx) {
ArrayList<Object> cache = ctx.mServiceCache;
Object service;
synchronized (cache) {
if (cache.size() == 0) {
// Initialize the cache vector on first access.
// At this point sNextPerContextServiceCacheIndex
// is the number of potential services that are
// cached per-Context.
for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
cache.add(null);
}
} else {
service = cache.get(mContextCacheIndex);
if (service != null) {
return service;
}
}
service = createService(ctx);
cache.set(mContextCacheIndex, service);
return service;
}
}
/**
* Override this to create a new per-Context instance of the
* service. getService() will handle locking and caching.
*/
public Object createService(ContextImpl ctx) {
throw new RuntimeException("Not implemented");
}
}
public Context getOuterContext() {
return null;
}
}
自定义类
package android.app;
public class V14to23ServiceFetcher extends ContextImpl.ServiceFetcher {
@Override
public Object createService(ContextImpl ctx) {
// do something here
return null;
}
}
例外代码
Class.forName("android.app.V14to23ServiceFetcher");
完整堆栈跟踪
05-19 14:55:16.813 29993-29993/? W/ResourcesManager: Asset path '/system/framework/android-support-v13.jar' does not exist or contains no resources.
05-19 14:55:16.813 29993-29993/? I/libthemeutils: Theme: libthemeutil.so load success
05-19 14:55:16.813 29968-29968/? I/art: Rejecting re-init on previously-failed class java.lang.Class<android.app.V14to23ServiceFetcher>
05-19 14:55:16.813 29968-29968/? I/art: Rejecting re-init on previously-failed class java.lang.Class<android.app.V14to23ServiceFetcher>
05-19 14:55:16.813 29968-29968/? D/AndroidRuntime: Shutting down VM
Process: a.b.c.com.appres, PID: 29968
java.lang.IllegalAccessError: android.app.V14to23ServiceFetcher
at dalvik.system.DexFile.defineClassNative(Native Method)
at dalvik.system.DexFile.defineClass(DexFile.java:226)
at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:219)
at dalvik.system.DexPathList.findClass(DexPathList.java:321)
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:54)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at com.a.b.c.d.install(ResourcesPatch.java:227)
at com.a.b.c.e.installRes(PatchManager.java:53)
at a.b.c.com.appres.App.onCreate(App.java:29)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1012)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4598)
at android.app.ActivityThread.access$1500(ActivityThread.java:154)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1380)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5308)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:913)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:708)