Экземпляр абстрактного класса со скрытым конструктором

Мне нужно создать экземпляр абстрактного класса со скрытым конструктором, класс выглядит следующим образом:

public abstract class TestClass { /** * @hide */ public TestClass() { } } 

Создание конкретного класса не работает, потому что конструктор не отображается и вызов конструктора через API отражения также не работает, потому что класс является абстрактным.

Мне нужно создать экземпляр android.print.PrintDocumentAdapter.LayoutResultCallback

Я столкнулся с одной и той же проблемой (точно для одного и того же класса), и у меня есть лучшее решение, чем замена android.jar на framework.jar, как это было предложено в другом ответе.

В решении используется библиотека dexmaker . (Вам понадобится dexmaker.1.4.jar и dexmaker-dx.1.4.jar). Это библиотека, которая генерирует байт-код во время выполнения для VM Dalvik (виртуальная машина, используемая в android).

Эта библиотека имеет класс ProxyBuilder который генерирует прокси для абстрактного класса. Прокси – это объект, который расширяет абстрактный класс и реализует методы, отправив их в экземпляр java.lang.reflect.InvocationHandler который вы укажете.

ProxyBuilder почти идентичен java.lang.refect.Proxy , за исключением того, что java.lang.refect.Proxy работает только для интерфейсов, а proxyBuilder ProxyBuilder работает для абстрактных классов, что нам и нужно для нашей проблемы.

Код:

 public static PrintDocumentAdapter.LayoutResultCallback getLayoutResultCallback(InvocationHandler invocationHandler, File dexCacheDir) throws IOException{ return ProxyBuilder.forClass(PrintDocumentAdapter.LayoutResultCallback.class) .dexCache(dexCacheDir) .handler(invocationHandler) .build(); } 

Логика обратного вызова реализована в invocationHandler который вы предоставляете. cacheDir – это некоторый каталог, в котором dexmaker может хранить некоторые файлы.

В этом учебном пособии рассматривается вопрос о том, как делать то, что вы спрашиваете: https://devmaze.wordpress.com/2011/01/18/using-com-android-internal-part-1-introduction/ . Я никогда не делал этого сам, поэтому я не могу ручаться за это.

Будьте осторожны: есть причина, что методы в API скрыты. Наиболее важным для разработчиков является то, что нет никакой гарантии, что метод будет придерживаться в течение какого-то периода времени, поскольку рассматриваемый метод не является частью какого-либо публичного API.