1. 程式人生 > >華為手機WebView長按不能複製,記一次少見奇葩bug解決之旅

華為手機WebView長按不能複製,記一次少見奇葩bug解決之旅

風起
接到反饋,說是之前一個老專案的詳情頁(html)長按不能複製了(華為mate9),uh…不記得需求裡有長按複製功能,不過現在原生webview是支援長按複製的,所以就是個預設需求了,那這個bug是要改的。

拿手邊的華為和小米試了一下,的確不能複製,然後到模擬器上跑了下,uh…長按可以複製。好吧,明確為適配問題。

雲湧

適配問題也分兩種,畢竟有前端童鞋參與吧。那就先確定誰的適配問題。

模擬器能複製,真機的專案中不能複製,那真機自帶的瀏覽器呢,copy了Url到真機瀏覽器上跑了下,可以複製啊,說明這個web頁在通用頁面上是可以複製的。那就是說,咱的webview有問題唄。。尷尬,webview這塊挺容易出問題的,好吧,那就逮住 setting,Webclient,WebChromeClient這幾個關鍵項來逐個排查唄。。

滄桑

然而,在嘗試多次,搜尋多次後,無奈發現,不能複製就是不能複製。。小樣,跟我槓上了,這時候就想,會不會是專案主題或者Style影響了呢,畢竟長按複製有個小彈窗啊,還是可能會受這些影響的。

於是乎,專案中各種Theme和Style看啊,試啊,結果,要複製,是不行的。

這回快服了,靈機一動,來吧,開個demo,弄個最簡單的webview載入一下那個url(程式碼如下),納尼。。長按可以複製,悲劇了,華為真機一個最普通的webview開啟都沒有問題啊,還是專案中某個東東影響了結果。

唉,會是啥呢,在專案中寫了個最簡單的demo頁面,仍是下面這個

class MainActivity : AppCompatActivity() {

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        webView.settings.javaScriptEnabled = true
        webView.webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
                view?.loadUrl(request?.url.toString())
                return true
            }
        }
        webView.loadUrl("https://blog.csdn.net/cysion1989/article/details/73431003")
    }
}

然後,替換進入出問題的詳情頁面(頁面X),即由原來的頁面A->頁面X;變成了現在的頁面A -> Demo頁面,,然而,不能複製就是不能複製。。

柳暗

看來肯定是專案某個地方影響了,主題,樣式或者其它全域性配置嗎?
這樣,把Demo頁面改成了Launcher頁面,開啟就進來,發現能複製。看來這些都不影響啊。那麼一定是某處程式碼有問題,冥冥中影響了唄。這時候把頁面A的前頁面P找出來,把原來的頁面P->頁面A改成了頁面P->Demo頁面,發現,能複製了。。

問題總算定位差不多了,原來是頁面A中某個程式碼不老實,影響了webview,可是看著頁面A的程式碼也挺老實啊,程式碼都跟WebView沒關係。

入定

好吧,服了,採用註釋大法,一層一層的註釋,然後重新執行,終於讓我逮到了那個奇葩的傢伙。。

原專案中為了在頁面A做個輪播,使用了AsyncTask(老專案嘛),這個Task為了無限執行,自然會在其doInBackground開個無限迴圈,當我註釋掉這個迴圈的時候,這篇部落格就出來了。。能複製的終歸能複製了!!

花明

AsyncTask裡做無限迴圈任務,只要迴圈沒有結束,華為的Webview就不能長按複製。。可能還有小米~有下面程式碼為證,有興趣的可以試試。

模擬器沒問題,說明官方底層程式碼是沒有問題的,華為出現了,這個鍋也只能他們背了,具體他們改了啥,或許以後有機會能知道吧。。
知道了問題所在,自然就好解決了。

class MainActivity : AppCompatActivity() {

    @SuppressLint("SetJavaScriptEnabled")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        webView.settings.javaScriptEnabled = true
        webView.webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
                view?.loadUrl(request?.url.toString())
                return true
            }
        }
        webView.loadUrl("https://blog.csdn.net/cysion1989/article/details/73431003")
        TmpTask().execute()
    }
}

class TmpTask : AsyncTask<Void, Void, Void>() {
    override fun doInBackground(vararg params: Void?): Void? {
        while (true){
        }
        return null
    }
}

一次比較完整的解決bug的流程,記錄一下,或許對讀者有幫助呢。