webview中的图标显示不同的Kitkat版本和页面加载问题。(例如,菜单图标)

时间:2017-12-13 06:40:31

标签: web-applications webview

Code for loading WebView. Screen appear white when loading on KitKat device.I used WebChromeClient in which override onProgressChanged() method.I used the following code.It works well on other devices greater than KitKat. Is there any solution for that.I read android developers doc but didn't get.Thanks.This is url private String url="https://xxxx.com/";



private void initWebview()
    {
        //Timer myTimer = new Timer();
        //Start this timer when you create you task
        //myTimer.schedule(new loaderTask(), 3000,1); // 3000 is delay in millies

        //webView.setWebChromeClient(new MyWebChromeClient(this));

            webView.setWebChromeClient(new MyWebChromeClient(this) {

              @Override
              public void onPermissionRequest(final PermissionRequest request) {
              //super.onPermissionRequest(request);
               runOnUiThread(new Runnable() {
               @TargetApi(Build.VERSION_CODES.LOLLIPOP)
               @Override
               public void run() {
               if (request.getOrigin().toString().equals(url))
                 {
                  request.grant(request.getResources());
                  }else
                 {
                  request.deny();
                 }
                }
               });
             }
          }
       );

            webView.setWebViewClient(new WebViewClient()
            {
                @Override
                public void onPageStarted(WebView view, String url, Bitmap favicon) {
                    super.onPageStarted(view, url, favicon);
                    progressBar.setVisibility(View.VISIBLE);
                }

                @Override
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    view.loadUrl(url);
                    return true;
                }

                @Override
                public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                    super.onReceivedSslError(view, handler, error);
                    handler.proceed();
                }

                @Override
                public void onReceivedError(WebView view, int errorCode,
                                            String description, String failingUrl) {

                    Log.i(TAG, "GOT Page error : code : " + errorCode + " Desc : " + description);
                    showError(OpenWebAppActivity.this, errorCode);
                    //TODO We can show customized HTML page when page not found/ or server not found error.
                    super.onReceivedError(view, errorCode, description, failingUrl);
                }


                @Override
                public void onPageFinished(WebView view, String url) {
                    super.onPageFinished(view, url);
                    isPageLoadedComplete = true;
                    timeout=false;
                    progressBar.setVisibility(View.GONE);
                }
            });
    }

私有类MyWebChromeClient扩展了WebChromeClient     {         上下文上下文;

    public MyWebChromeClient(Context context) {
        this.context = context;
        timeout=true;
    }

    @Override
    public void onReceivedTitle(WebView view, String title) {
        super.onReceivedTitle(view, title);
        getWindow().setTitle(title);
    }

    @Override
    public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
        AlertDialog dialog = new AlertDialog.Builder(view.getContext()).
                setMessage(message).
                setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //do nothing
                    }
                }).create();
        dialog.show();
        result.confirm();
        return true;
    }

加载WebView的代码。在KitKat设备上加载时,屏幕显示为白色。我使用了WebChromeClient,其中覆盖了onProgressChanged()方法。我使用了以下代码。它在大于KitKat的其他设备上运行良好。有什么解决方案吗。我读了android开发者文档,但没有得到。谢谢。

1 个答案:

答案 0 :(得分:0)

The Actual footage taken from the emulator under KitKat

首先:

WebViewClient和WebChromeClient之间在使用方式上存在很大差异。引自官方文档:

WebViewClient

  

/ **        *设置将接收各种通知的WebViewClient        * 要求。这将取代当前的处理程序。        *        * @param客户端是WebViewClient的一个实现        * @see #getWebViewClient        * /

WebChromeClient

  

/ **        *设置chrome处理程序。这是WebChromeClient的实现        *用于处理JavaScript对话框,favicon,标题和进度。        *这将取代当前的处理程序。        *        * @param客户端WebChromeClient的实现        * @see #getWebChromeClient        * /

因此,如果您的问题只是Kitkat并加载网页,那么您根本不需要使用 WebChromeClient

如此公平这可能是主要问题,同时我无法测试网页xxxx

因为我在保护路由器后面给了我错误,但是我已经测试了谷歌已加载的图像已经正常工作,你可以在图像中看到实际上在KitKat模拟器上采取它并且它工作得很好。

所以基本上我只是稍微调整了你的代码,这是最终使用的代码。

<强> GeneralWebViewClient

public class GeneralWebViewClient extends WebViewClient {

    private WebViewListener onWebViewListener;

    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        super.onPageStarted(view, url, favicon);
        if (onWebViewListener != null) {
            onWebViewListener.onPageStarted(view, url, favicon);
        }
    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        view.loadUrl(url);
        return true;
    }

    /**
     * Important to notice! This method must be used on in Lollipop and above versions because the old one is deprecated so we annotate it, but we have to use the old one for Pre-Lollipop devices
     * @param view
     * @param request
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
        view.loadUrl(request.getUrl().toString());
        return super.shouldOverrideUrlLoading(view, request);
    }

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        super.onReceivedSslError(view, handler, error);
        handler.proceed();
    }

    @Override
    public void onReceivedError(WebView view, int errorCode,
                                String description, String failingUrl) {

        if (onWebViewListener != null) {
            onWebViewListener.onPageLoadingError(description, errorCode, false, null);
        }
        super.onReceivedError(view, errorCode, description, failingUrl);
    }


    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);

        if (onWebViewListener != null) {
            onWebViewListener.onPageFinished(view, url);
        }
    }


    /**
     * Simple setter for the listener
     *
     * @param onWebViewListener
     */
    public void setOnWebViewListener(@Nullable WebViewListener onWebViewListener) {
        this.onWebViewListener = onWebViewListener;
    }


    /**
     * Add all needed logic to this method to release your used resources when the caller gets destroyed
     */
    private void releaseResources() {
        onWebViewListener = null;
    }


    /**
     * A class which handles a lifecycle events if attached. It is always a good idea to release resources when the caller gets destroyed, so this is a small tune up for that.
     */
    public class LifeCycleObserver implements LifecycleObserver {
        @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        private void clean() {
            releaseResources();
        }
    }

    /**
     * So to make the code less in our main place, we just create  a set of needed callbacks to pass to the caller and just ignore the rest to keep main place clean and tidy
     * Important to notice the code {@code onPageLoadingError} which takes boolean argument {code sslError} ,hence indicating  whether it was an error from Sssl or no, and accordingly
     * {@code {@link SslErrorHandler}} can be null.
     */
    public interface WebViewListener {
        void onPageStarted(WebView view, String url, Bitmap favIcon);

        void onPageFinished(WebView view, String url);

        void onPageLoadingError(String error, int errorCode, boolean sslError, @Nullable SslErrorHandler handler);
    }
}

GeneralWebViewClient类的实现(MainActivity或您要处理WebView加载的活动)

public class MainActivity extends AppCompatActivity implements GeneralWebViewClient.WebViewListener {

    private static final String TAG = "tag";
    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        webView = findViewById(R.id.webView);

        GeneralWebViewClient generalWebViewClient = new GeneralWebViewClient();
        generalWebViewClient.setOnWebViewListener(this);

        GeneralWebViewClient.LifeCycleObserver lifeCycleObserver = generalWebViewClient.new LifeCycleObserver();
        getLifecycle().addObserver(lifeCycleObserver);

        webView.setWebViewClient(generalWebViewClient);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl("http://www.google.com");
    }


    @Override
    public void onPageStarted(WebView view, String url, Bitmap favIcon) {
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void onPageFinished(WebView view, String url) {
        isPageLoadedComplete = true;
        timeout = false;
        progressBar.setVisibility(View.GONE);
    }

    @Override
    public void onPageLoadingError(String error, int errorCode, boolean sslError, @Nullable SslErrorHandler handler) {
        if (sslError) {
            handler.proceed();
        } else {
            Log.i(TAG, "GOT Page error : code : " + errorCode + " Desc : " + error);
            showError(OpenWebAppActivity.this, errorCode);
        }

    }

}

我真的不认为需要使用Chrome客户端。如果你需要它,那么在什么情况下呢?哦,只是出于安全目的:

不要忘记添加互联网权限 - <uses-permission android:name="android.permission.INTERNET"></uses-permission>