I'm working on an SDK for Android. As part of this SDK, I need to set my own WebViewClient
to a WebView
of an application where the WebView
and the SDK are integrated (meaning not part of my SDK).
For this reason, this WebView
might have already been set with a WebViewClient
and in this case, I need to get the instance of this WebViewClient
from the WebView
set my own WebViewClient
to it and forward the callback methods of my WebViewCleint
to the originally configured one that was set by the developer of the app.
I noticed that from API V26 there is a getWebViewClient method for the WebView
class. but obviously, I'm looking for a way to do this on previous versions as well. Maybe there is some kind of way to do this using the support libs?
Does someone know how can I get the instance of the set WebViewClient in the WebView in older versions? using Reflection or any other method?
I managed to get the instance of the WebViewClient using reflection like so:
Object providerInstance = getProviderInstance();
Object contentsClientAdapter = getContentsClientAdapter(providerInstance);
Object webViewClient = getWebViewClientFromClientAdapter(contentsClientAdapter);
if (webViewClient instanceof WebViewClient) {
mPreviousWebViewClient = (WebViewClient) webViewClient;
}
And those are the three methods to drill down the WebView
object to get the WebViewClient
object:
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;
}
But I'm really hoping to find some kind of another way to do the same. Something that will be less prone to breakage.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With