Как получить экземпляр WebviewClient из WebView, а не API 26 в Android?
Я работаю над SDK для Android. В рамках этого SDK мне нужно установить свой собственный WebViewClient
к WebView
приложения, где WebView
и SDK интегрированы (т.е. не являются частью моего SDK).
По этой причине это WebView
возможно, уже был установлен с WebViewClient
и в этом случае мне нужно получить экземпляр этого WebViewClient
от WebView
установить свой собственный WebViewClient
к нему и переслать методы обратного вызова моего WebViewCleint
на изначально настроенный, который был установлен разработчиком приложения.
Я заметил, что из API V26 есть метод getWebViewClient для WebView
учебный класс. но, очевидно, я ищу способ сделать это и в предыдущих версиях. Может быть, есть какой-то способ сделать это с помощью библиотек поддержки?
Кто-нибудь знает, как я могу получить экземпляр установленного WebViewClient в WebView в более старых версиях? используя Reflection или любой другой метод?
1 ответ
Мне удалось получить экземпляр WebViewClient, используя отражение следующим образом:
Object providerInstance = getProviderInstance();
Object contentsClientAdapter = getContentsClientAdapter(providerInstance);
Object webViewClient = getWebViewClientFromClientAdapter(contentsClientAdapter);
if (webViewClient instanceof WebViewClient) {
mPreviousWebViewClient = (WebViewClient) webViewClient;
}
И это три метода, чтобы развернуть WebView
объект, чтобы получить WebViewClient
объект:
public Object getProviderInstance() {
Object returnValue = null;
try {
Class<? extends WebView> mWebViewClass = mWebView.getClass();
Field providerField = mWebViewClass.getDeclaredField("mProvider");
providerField.setAccessible(true);
Object mProvider = providerField.get(mWebView);
returnValue = mProvider;
} catch (NoSuchFieldException aE) {
aE.printStackTrace();
} catch (IllegalAccessException aE) {
aE.printStackTrace();
}
return returnValue;
}
private Object getContentsClientAdapter(Object aProviderInstance) {
Object returnValue = null;
try {
Class<?> aClass = aProviderInstance.getClass();
Field contentsClientAdapterField = aClass.getDeclaredField("mContentsClientAdapter");
contentsClientAdapterField.setAccessible(true);
Object mContentsClientAdapter = contentsClientAdapterField.get(aProviderInstance);
returnValue = mContentsClientAdapter;
} catch (NoSuchFieldException aE) {
aE.printStackTrace();
} catch (IllegalAccessException aE) {
aE.printStackTrace();
}
return returnValue;
}
private Object getWebViewClientFromClientAdapter(Object aContentsClientAdapter) {
Object returnValue = null;
try {
Class<?> aClass = aContentsClientAdapter.getClass();
Field WebViewClientField = aClass.getDeclaredField("mWebViewClient");
WebViewClientField.setAccessible(true);
Object mWebViewClient = WebViewClientField.get(aContentsClientAdapter);
returnValue = mWebViewClient;
} catch (NoSuchFieldException aE) {
aE.printStackTrace();
} catch (IllegalAccessException aE) {
aE.printStackTrace();
}
return returnValue;
}
Но я действительно надеюсь найти какой-то другой способ сделать то же самое. То, что будет менее подвержено поломкам.