java.lang.IllegalArgumentException: Kotlin 和 WebView 中指定为非空的参数为空

22
我试图使用自定义HTML字符串填充我的WebView,并在未加载时显示进度,完成后隐藏它。
以下是我的代码:
webView.settings.javaScriptEnabled = true
webView.loadDataWithBaseURL(null, presentation.content, "text/html", "utf-8", null)

webView.webViewClient = object : WebViewClient() {

  override fun onPageStarted(view: WebView, url: String, favicon: Bitmap) {
    super.onPageStarted(view, url, favicon)
    webViewProgressBar.visibility = ProgressBar.VISIBLE
    webView.visibility = View.INVISIBLE
  }

  override fun onPageCommitVisible(view: WebView, url: String) {
    super.onPageCommitVisible(view, url)
    webViewProgressBar.visibility = ProgressBar.GONE
    webView.visibility = View.VISIBLE
  }
}

我遇到了这个错误,但它没有指向我的代码的任何一行:

E/AndroidRuntime: FATAL EXCEPTION: main

java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter favicon
at com.hidglobal.tmt.app.mobiBadge.ui.presentation.PresentationActivity$showPresentation$1.onPageStarted(PresentationActivity.kt)
at com.android.webview.chromium.WebViewContentsClientAdapter.onPageStarted(WebViewContentsClientAdapter.java:215)
at org.chromium.android_webview.AwContentsClientCallbackHelper$MyHandler.handleMessage(AwContentsClientCallbackHelper.java:20)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

2
它说onPageStarted函数中的参数favicon被定义为非空,但是它接收到了空值。因此,你可以将其定义为Bitmap? - Stefan Golubović
3个回答

54

我有同样的问题。

 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)

我只是按照以下步骤执行: 更改

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

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

由于Kotlinlang不允许使用null参数。只需将Bitmap更改为Bitmap?那么它就可以正常运行。希望这可以帮助其他人。


1
超级棒的解决方案 - Kiran Benny Joseph
但是我有300多个方法。如何轻松处理? - Gk Mohammad Emon
@GkMohammadEmon 一次性查找和替换。 - Naveen Rao
完美答案。 - Dheeraj Rijhwani
很好的解决方案,非常棒!确实!! - Najib.Nj

31

TL; DR

Fix the issue by making the favicon parameter nullable by changing the signature to favicon: Bitmap?.

Full response

The onPageStarted method receives a null value for the favicon parameter, which is defined as a non-nullable Kotlin type. This may occur when interacting with Java code, where any platform type (e.g. objects from Java) can be null. To handle this, you can choose to either use the platform type "as-is" or make it nullable. If you choose to use it "as-is", null-checks are relaxed and you may encounter NullPointerExceptions. To fix this particular issue, change the signature of the favicon parameter to favicon: Bitmap? to make it nullable.

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
}
  • 将其转换为特定类型(可以为空或非空)。在这种情况下,Kotlin编译器会将其视为“常规” Kotlin类型。例如:

  • 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
    }
    

    但是,如果你强制使用非空类型,却得到了null,那么就会抛出异常。例如:

    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
    }
    

    在这种情况下,你可以“玩得保险”,并强制变量可为空——这样永远不会失败,但可能会使代码更难阅读:

    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!"
    }
    

    您可以在代码中使用后面的示例来处理 bitmap 为 null 的情况:

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

    1
    是的,我正在将Java代码转换过来,没有注意到这个明显的问题。谢谢。 - K.Os
    也许你也能看到问题,但我的进度条根本没有出现。这是定义进度条的正确位置吗? - K.Os
    1
    HTML页面加载需要多长时间?也许这很快,以至于您的进度条没有时间消失/重新出现,如果您加载一些本地内容可能会出现这种情况。 - user2340612

    -1
    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;
            }
    
        }
    

    在 onCreate 方法内---

    initWebView()

    binding.webView.loadUrl(urlName)
    

    尝试一下,以实现平滑的网页视图 URL 加载。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接