Как получить экземпляр 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;
}

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

Другие вопросы по тегам