1. 程式人生 > >AgentWeb在Kotlin開發使用中出現WebView的onPageStarted中favicon為空導致崩潰

AgentWeb在Kotlin開發使用中出現WebView的onPageStarted中favicon為空導致崩潰

最新專案中使用了AgentWeb的一個WebView封裝庫,使用kotlin語言開發時候出現了IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter favicon的問題,而在Java語言情況下不會出現崩潰。

  • 場景:

    kotlin開發環境,使用AgentWeb,在WebActivity的onCreate中,AgentWeb初始配置如下

     //初始化AgentWeb物件
    mAgentWeb = AgentWeb.with(this) .setAgentWebParent( mLinearLayout, LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) ) .useDefaultIndicator() .
    setWebChromeClient(mWebChromeClient) .setWebViewClient(mWebViewClient)//注意這裡!!!!!!!! .setMainFrameErrorView(R.layout.agentweb_error_page, -1) .setSecurityType(AgentWeb.SecurityType.STRICT_CHECK) .setOpenOtherPageWays(DefaultWebClient.OpenOtherPageWays.ASK)//開啟其他應用時,彈窗諮詢使用者是否前往其他應用
    .interceptUnkownUrl() //攔截找不到相關頁面的Scheme .createAgentWeb() .ready() .go("http://www.google.com")
  • 問題

    開啟WebActivity會直接崩潰,錯誤日誌如下

    java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter favicon
            at com.zhiwei.services.webapp.BaseWebActivity$mWebViewClient$1.onPageStarted(Unknown Source:12)
            at com.just.agentweb.WebViewClientDelegate.onPageStarted(WebViewClientDelegate.java:80)
            at com.just.agentweb.DefaultWebClient.onPageStarted(DefaultWebClient.java:466)
            at xq.b(SourceFile:219)
            at alW.handleMessage(SourceFile:20)
            at android.os.Handler.dispatchMessage(Handler.java:106)
            at android.os.Looper.loop(Looper.java:193)
    

    問題清晰描述為在onPagestarted函式中favicon欄位為空,kotlin本身呼叫時候認為為非空的資料,現在為空,所以引起崩潰。

  • 解決方案

    • 如不需要特殊處理,可以移除setWebViewClient這個初始化配置

    • 若需要使用setWebViewClient,則需要同時設定一個useMiddlewareWebClient

      .setWEbViewClient(mWebViewClient)
      .useMiddlewareWebClient(object:MiddlewareWebClientBase(){
          //可以抽取出去,定義一個實現類也行,這裡使用了匿名內部類
          override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                          //定義一個bitmap,避免favicon為空,引起的崩潰
                          val ff = favicon ?: ImageUtils.drawable2Bitmap(AppUtils.getAppIcon())
                          super.onPageStarted(view, url, ff)
                      }
      })
      
    • 修改原始碼DefaultWebClient

      @Override
      	public void onPageStarted(WebView view, String url, Bitmap favicon) {
      		//在這裡處理favicon為空,defaultWebClient內部有Activity的弱引用
              //可以取Activity獲取到resource,來構建一個bitmap給faicon,
              //或者WebIconDatabase.getInstance().open(getDir("icons", MODE_PRIVATE).getPath());設定web的圖示
      		if (!mWaittingFinishSet.contains(url)) {
      			mWaittingFinishSet.add(url);
      		}
      		super.onPageStarted(view, url, favicon);
      
      	}
      
  • 原因分析:kotlin語言中若未宣告bitmap:Bitmap?為可null型別,則斷定就是非空,所以如果傳遞的值,是null值,就會崩潰。類似Java中@NonNull標記,而AgentWebDefaultWebClientWebViewClientdelegateonPageStarted函式,都是java檔案,裡面未做favicon的非空判斷。(似乎就是android webview的問題