mercredi 12 juillet 2017

How to override methods of a class (without interface implementation) I received in reflection:

I'm writing an SDK. In some logic of this SDK I need to recognize a WebView on screen attach a WebViewClient to it and use its methods like so:

 wv.setWebViewClient(new WebViewClient() {
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
                    if (!loadingFinished) {
                        redirect = true;
                    }

                    if (isCaptureMode()) {
                        wv.setAlpha(0.1f);
                    }

                    loadingFinished = false;
                    view.loadUrl(urlNewString);
                    return true;
                }

                @Override
                public void onPageStarted(WebView view, String url, Bitmap facIcon) {
                    loadingFinished = false;
                    ABLogger.d("onWebViewDetected() onPageStarted");
                }

                @Override
                public void onPageFinished(WebView view, String url) {
                    if (!redirect) {
                        loadingFinished = true;
                    }

                    if (loadingFinished && !redirect) {
                        ABLogger.d("onWebViewDetected() onPageFinished");
                        onWebViewLoaded(view, true);
                    } else {
                        redirect = false;
                    }
                }

                @Override
                public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                    super.onReceivedError(view, request, error);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        ABLogger.e("Failed to load site with url '%s'. error: %s", view.getUrl(), error.getDescription());
                    } else {
                        ABLogger.e("Failed to load site with url '%s'. error: %s", view.getUrl(), error.toString());
                    }
                    onWebViewLoaded(view, false);
                }
            });

And this works well, In some other cases I'm dealing with Cordova apps in which case I receiving a SystemWebView view instead of WebView view. In this case the SystemWebView expects to get a SystemWebViewClient class in the setWebViewClient method. Now I don't have the Cordova class in my SDK. So I'm doing it all using reflection:

private Class getCordovaSystemWebViewClient() {
    if (mSystemWebViewClient == null) {
        try {
            this.mSystemWebViewClient = Class.forName(MapperBase.KEY_VIEW_CORDOVA_SYSTEM_WEB_VIEW_CLIENT);
        } catch (Exception e) {
            return null;
        }
    }
    return mSystemWebViewClient;
}
....

Class classCordovaSystemWebViewClient = getCordovaSystemWebViewClient();
Constructor constructor = classCordovaSystemWebViewClient.getConstructors()[0];
Object webViewClient = null;
Object o = constructor.newInstance(null);

The Question: Now that I have the SystemWebViewClient class, how can I override it's methods as I do with the regular WebViewClient?





Aucun commentaire:

Enregistrer un commentaire