WebView白屏优化的一些整理

Posted 且听真言

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebView白屏优化的一些整理相关的知识,希望对你有一定的参考价值。

WebView打开出现白屏和速度慢的一些原因:

1.H5页面运行在独立进程中,H5打开需要首先启动Web进程。

 

2.每次关闭H5页面会通过exitProcess(0)关闭Web 进程。

优化方案:

1.Web进程预启动。

通过绑定服务的方式启动一个Service来对WebView进程进行预热。

<service
            android:name=".service.PreWebService"
            android:enabled="true"
            android:process=":Webview"
            android:exported="true">
        </service>
class PreWebService : Service() 

    override fun onBind(intent: Intent): IBinder? 
        return null
    

 

val intent = Intent(context, PreWebService::class.java)
context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)
 private val mConnection =

        object : ServiceConnection 
            override fun onServiceConnected(name: ComponentName?, service: IBinder?) 
                mBound = true
            

            override fun onServiceDisconnected(name: ComponentName?) 
                mBound = false
            

        

 

if (mBound) 
	context.unbindService(mConnection)
	mBound = false


2.WebView 预创建与复用。

class WebViewManager private constructor() 
    companion object 
        @Volatile
        private var INSTANCE: WebViewManager? = null

        private fun instance() = INSTANCE ?: synchronized(this) 
            INSTANCE ?: WebViewManager().also 
                INSTANCE = it
            
        

        fun prepare(context: Context) 
            instance().prepare(context)
        

        fun obtain(context: Context): WebView 
            return instance().obtain(context)
        

        fun recycle(webView: WebView) 
            instance().recycle(webView)
        

        fun destroy(context: Context) 
            instance().destroy(context)
        

        fun goBack(webView: WebView, originalUrl: String): Boolean 
            val canBack = webView.canGoBack()
            if (canBack) webView.goBack()
            val backForwardList = webView.copyBackForwardList()
            val currentIndex = backForwardList.currentIndex
            if (currentIndex == 0) 
                val currentUrl = backForwardList.currentItem?.url
                val currentHost = Uri.parse(currentUrl).host
                //栈底不是链接则直接返回
                if (currentHost.isNullOrBlank()) return false
                //栈底链接不是原始链接则直接返回
                if (originalUrl != currentUrl) return false
            
            return canBack
        
    

    private val webViewCache: MutableList<WebView> = ArrayList(1)

    private var mBound = false

    fun prepare(context: Context) 
        if (webViewCache.isEmpty()) 
            Looper.myQueue().addIdleHandler 
                webViewCache.add(create(MutableContextWrapper(context)))
                val intent = Intent(context, PreWebService::class.java)
                context.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)
                false
            
        
    

    fun obtain(context: Context): WebView 
        if (webViewCache.isEmpty()) 
            webViewCache.add(create(MutableContextWrapper(context)))
        
        val webView = webViewCache.removeFirst()
        val contextWrapper = webView.context as MutableContextWrapper
        contextWrapper.baseContext = context
        webView.clearHistory()
        webView.resumeTimers()
        return webView
    

    fun recycle(webView: WebView) 
        try 
            webView.stopLoading()
            webView.loadDataWithBaseURL("about:blank", "", "text/html", "utf-8", null)
            webView.clearHistory()
            webView.pauseTimers()
            val parent = webView.parent
            if (parent != null) 
                (parent as ViewGroup).removeView(webView)
            
            val contextWrapper = webView.context as MutableContextWrapper
            contextWrapper.baseContext = webView.context.applicationContext
         catch (e: Exception) 
            e.printStackTrace()
         finally 
            if (!webViewCache.contains(webView)) 
                webViewCache.add(webView)
            
        
    

    fun destroy(context: Context) 
        try 
            if (mBound) 
                context.unbindService(mConnection)
                mBound = false
            
            webViewCache.forEach 
                it.removeAllViews()
                it.destroy()
                webViewCache.remove(it)
            
         catch (e: Exception) 
            e.printStackTrace()
        
    

    private fun create(context: Context): WebView 
        return WebView(context)
    

    private val mConnection =

        object : ServiceConnection 
            override fun onServiceConnected(name: ComponentName?, service: IBinder?) 
                mBound = true
            

            override fun onServiceDisconnected(name: ComponentName?) 
                mBound = false
            

        

 

3.WebView页面关闭时不关闭Web进程,只做资源清理。

以上是关于WebView白屏优化的一些整理的主要内容,如果未能解决你的问题,请参考以下文章

小程序 webview 部分用户打开后白屏

Android layer type与WebView白屏-第一次加载webview很慢

WebView 和加载数据在 Android Constraintlayout 中显示白屏

WebView 不一致地显示白屏 react-native

Android layer type与WebView白屏以及WebView不随动画而动的问题

Android webview只加载10%且出现白屏问题排查解决