An instance of an abstract class with a hidden constructor
I need to create an instance of an abstract class with a hidden constructor, which looks like this:
public abstract class TestClass {
/**
* @hide
*/
public TestClass() {
}
}
Creating a concrete class doesn’t work because the constructor
isn’t visible, and calling the constructor through the reflection API doesn’t work because the class is abstract.
I need to create an instance of android.print.PrintDocumentAdapter.LayoutResultCallback
Solution
I’m having the exact same problem (even for the exact same class) and I have a better solution than the one suggested in the answer to replace android.jar with framework.jar.
The solution uses dexmaker library . (You will need dexmaker.1.4.jar and dexmaker-dx.1.4.jar.) This is a library that generates bytecode at runtime for the Dalvik VM (a VM used in android).
This library has a class called ProxyBuilder
, which generates a proxy for abstract classes. A proxy is an object that extends an abstract class and implements methods by dispatching them to the java.lang.reflect.InvocationHandler
instance that you specify.
ProxyBuilder is almost identical to java.lang.refect.Proxy,
except that java.lang.refect.Proxy
applies only to interfaces, while dexmaker’s ProxyBuilder
applies to abstract classes
.
This is exactly what we need to solve the problem.
The code is all :
public static PrintDocumentAdapter.LayoutResultCallback getLayoutResultCallback(InvocationHandler invocationHandler,
File dexCacheDir) throws IOException{
return ProxyBuilder.forClass(PrintDocumentAdapter.LayoutResultCallback.class)
.dexCache(dexCacheDir)
.handler(invocationHandler)
.build();
}
The callback logic is implemented in the invocationHandler
that you provide.
cacheDir
is a directory where dexmaker can store some files.