java.lang.IllegalArgumentException: Parameter specified as non-null is null for Kotlin and WebView

后端 未结 3 821
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-07 01:09

I am trying to populate my WebView with custom HTML string and trying to show progress when it is not loaded, and hide it when finished.

Here is my code:

<         


        
相关标签:
3条回答
  • 2020-12-07 01:38
    private void initWebView() {
        webView.setWebChromeClient(new MyWebChromeClient(getActivity()));
            webView.setWebViewClient(new WebViewClient() {
                @Override
                public void onPageStarted(WebView view, String url, Bitmap favicon) {
                    super.onPageStarted(view, url, favicon);
                    progressBar.setVisibility(View.VISIBLE);
                    getActivity().invalidateOptionsMenu();
                }
    
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    webView.loadUrl(url);
                    return true;
                }
    
                @Override
                public void onPageFinished(WebView view, String url) {
                    super.onPageFinished(view, url);
                    progressBar.setVisibility(View.GONE);
                    getActivity().invalidateOptionsMenu();
                }
    
                @Override
                public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                    super.onReceivedError(view, request, error);
                    progressBar.setVisibility(View.GONE);
                    getActivity().invalidateOptionsMenu();
                }
            });
            webView.clearCache(true);
            webView.clearHistory();
            webView.getSettings().setJavaScriptEnabled(true);
            webView.setHorizontalScrollBarEnabled(false);
            webView.setOnTouchListener(new View.OnTouchListener() {
                public boolean onTouch(View v, MotionEvent event) {
    
                    if (event.getPointerCount() > 1) {
                        //Multi touch detected
                        return true;
                    }
    
                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN: {
                            // save the x
                            m_downX = event.getX();
                        }
                        break;
    
                        case MotionEvent.ACTION_MOVE:
                        case MotionEvent.ACTION_CANCEL:
                        case MotionEvent.ACTION_UP: {
                            // set x so that it doesn't move
                            event.setLocation(m_downX, event.getY());
                        }
                        break;
                    }
    
                    return false;
                }
            });
        }
    
        private class MyWebChromeClient extends WebChromeClient {
            Context context;
    
            public MyWebChromeClient(Context context) {
                super();
                this.context = context;
            }
    
        }
    

    Inside on create---

    initWebView()

    binding.webView.loadUrl(urlName)
    

    Just try it for smooth web view URL load.

    0 讨论(0)
  • 2020-12-07 01:53

    I have the same problem.

     java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter favicon
        at com.haoyong.szzc.module.share.view.activity.WebActivity$MyWebViewClient.onPageStarted(WebActivity.kt:0)
        at com.android.webview.chromium.WebViewContentsClientAdapter.onPageStarted(WebViewContentsClientAdapter.java:495)
        at com.android.org.chromium.android_webview.AwContentsClientCallbackHelper$MyHandler.handleMessage(AwContentsClientCallbackHelper.java:122)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5313)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1116)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:809)
    

    I just do it as follows: change

    override fun onPageStarted(view: WebView, url: String, favicon: Bitmap) {
                super.onPageStarted(view, url, favicon)
            }
    

    to

     override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
                super.onPageStarted(view, url, favicon)
            }
    

    Because it is not allowed to use the null parameter in the Kotlinlang. just change the Bitmap to Bitmap? Then it will work well. Hope this can help the other people.

    0 讨论(0)
  • 2020-12-07 01:54

    TL; DR

    The system passes a null favicon but it is defined as a non-nullable Kotlin type. You can fix it by changing the signature to favicon: Bitmap? to make it nullable.

    Full response

    The issue is that method onPageStarted is called (by the system) passing a null value for the favicon parameter. This may happen when there is some Kotlin code that is interoperating with Java code (by default you should get nullable objects).

    Any platform type (e.g. any objects coming from Java) can be null, because Java has no special notation to tell that something can or cannot be null. For that reason when you use platform types in Kotlin you can choose to either:

    • use it "as-is"; the consequence in such case is that (from documentation)

      Null-checks are relaxed for such types, so that safety guarantees for them are the same as in Java

      Hence you may get NullPointerExceptions, like in the following example:

      fun main(args: Array<String>) {
          val array = Vector<String>() // we need to Vector as it's not mapped to a Kotlin type
          array.add(null)
          val retrieved = array[0]
          println(retrieved.length) // throws NPE
      }
      
    • cast it to a specific type (either nullable or non-nullable); in this case the Kotlin compiler will treat it as a "normal" Kotlin type. Example:

      fun main(args: Array<String>) {
          val array = Vector<String>() // we need to Vector as it's not mapped to a Kotlin type
          array.add("World")
          val retrieved: String = array[0] // OK, as we get back a non-null String
          println("Hello, $retrieved!") // OK
      }
      

      However, this will throw an exception if you enforce a non-nullable type but then get back null. Example:

      fun main(args: Array<String>) {
          val array = Vector<String>() // we need to Vector as it's not mapped to a Kotlin type
          array.add(null)
          val retrieved: String = array[0] // we force a non-nullable type but get null back -> throws NPE
          println("Hello, World!") // will not reach this instruction
      }
      

      In such case you can "play it safe" and enforce the variable to be nullable – this will never fail, but could make the code harder to read:

      fun main(args: Array<String>) {
          val array = Vector<String>() // we need to Vector as it's not mapped to a Kotlin type
          array.add(null)
          val retrieved: String? = array[0] // OK since we use a nullable type
          println("Hello, $retrieved!") // prints "Hello, null!"
      }
      

    You can use the latter example in your code to cope with the bitmap being null:

    override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
        ...
    }
    
    0 讨论(0)
提交回复
热议问题