如何使用stetho调试webview

在Android Studio中使用com.facebook.stetho:stetho库来通过Chrome的开发者工具调试HTTP请求和响应以及H5页面(即Web内容),需要几个步骤来配置和启用Stetho。这里我将详细介绍如何在Android应用中进行设置。

1. 添加依赖

首先,确保在你的build.gradle(通常是app模块的)文件中添加了stethostetho-okhttp3的依赖。如果还没有添加,可以像这样添加:

dependencies {  
    // 其他依赖...  
    api 'com.facebook.stetho:stetho:1.5.0'
    api 'com.facebook.stetho:stetho-okhttp3:1.5.0'
    api 'com.facebook.stetho:stetho-js-rhino:1.5.0'
}

请检查最新版本,因为库的版本可能会更新。

2. 初始化Stetho

在你的Application类或者一个合适的初始化位置(如Activity的onCreate方法中,但最好在Application类中以避免重复初始化),初始化Stetho。

import com.facebook.stetho.Stetho;  
  
public class MyApplication extends Application {  
  
    @Override  
    public void onCreate() {  
        super.onCreate();  
  
        // 初始化Stetho  
        Stetho.initializeWithDefaults(this);  
  
        // 如果你使用OkHttp3,还需要额外配置OkHttpClient以使用Stetho的拦截器  
        // 这通常在你的网络请求初始化代码中完成  
    }  
}

3. 配置OkHttpClient以使用Stetho

对于OkHttp3,你需要在创建OkHttpClient实例时添加一个拦截器,以便Stetho可以捕获HTTP请求和响应。

import com.facebook.stetho.okhttp3.StethoInterceptor;  
import okhttp3.OkHttpClient;  
  
OkHttpClient client = new OkHttpClient.Builder()  
        .addNetworkInterceptor(new StethoInterceptor())  
        .build();

确保这个配置是在你的应用中进行网络请求之前完成的。

4. 使用Chrome进行调试

一旦你的应用在设备上运行,并且Stetho已经初始化,你可以通过以下步骤在Chrome中访问你的应用:

  1. 打开Chrome浏览器。
  2. 访问chrome://inspect
  3. 你应该能在Devices部分看到你的设备,点击它。
  4. 在出现的列表中,找到你的应用,点击inspect链接。
  5. 这将打开一个新的开发者工具窗口,你可以在这里查看网络请求、资源、控制台日志等,就像你在调试一个网页一样。

注意事项

  • 确保你的Android设备已经通过USB调试模式连接到你的电脑,并且Chrome能够识别到它。
  • 如果你的应用有多个进程或者多个组件(如Service),你可能需要确保Stetho在所有的相关进程中都被初始化。
  • 某些Android设备或Chrome版本可能存在兼容性问题,如果遇到问题,尝试更新你的设备或Chrome浏览器。

5. WebView 代码协助调试

这样就结束了吗?并没有!!!

一般网上的资料都是这样的,一番操作下发现是没什么用的,

进入我们的应用打开webview 界面,并没有弹出我们的应用和界面,如上所示,是空的,搜索相关内容也只是重复上述的1,2,3,4,

以下是我的解决方法:

获取到webview实例之后,设置可以调试的模式

    fun setDebugEnable(isDebugEnable: Boolean) {
        if (isDebugEnable) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                WebView.setWebContentsDebuggingEnabled(true)
            }
        }
    }
    fun setDomEnable(isDomEnable: Boolean) {
        this.isDomEnable = isDomEnable
        mWebView.settings.domStorageEnabled = isDomEnable
    }

这样的话,再进入谷歌浏览器就可以看到对应的

这个时候可以点击 inspect,可以查看对应的webview的内容进行分析了,以下代码是我的webview的基本代码,可参考:

 @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    private fun initBaseWebView() {
        mWebView = findViewById(R.id.web_webview)
        if (mWebView.visibility == View.GONE) {
            mWebView.visibility = View.VISIBLE
        }
        mWebSetting = mWebView.settings
        mWebSetting.javaScriptEnabled = true
        mWebSetting.setSupportZoom(true)
        mWebSetting.loadWithOverviewMode = true
        mWebSetting.builtInZoomControls = false
//        //静态安全检测  明文存储密码
        mWebSetting.savePassword = false
        //设置字体大小,需要和H5沟通是否去掉
        setFontSize(fontSize)
        //加载资源的时候总是允许
        mWebSetting.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
        //加载的时候支持缓存
//        mWebSetting.cacheMode = WebSettings.LOAD_NO_CACHE
        mWebSetting.cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK
        mWebSetting.loadsImagesAutomatically = true
        mWebSetting.allowFileAccess = true
        mWebSetting.allowFileAccessFromFileURLs = true
        mWebSetting.allowUniversalAccessFromFileURLs = true
        mWebSetting.mediaPlaybackRequiresUserGesture = false
        mWebSetting.domStorageEnabled = true
        mWebSetting.setAppCacheEnabled(true)
        //不删除缓存
//        mWebView.clearCache(true)
        mWebView.addJavascriptInterface(FinishActivityUtil(), "close")
        mWebView.addJavascriptInterface(BaseWebJsObject(), "BaseWebJsObject")
        mWebView.webChromeClient = WebViewChromeClient()
        mWebView.webViewClient = WebViewClient()
        mWebView.setOnLongClickListener(this)
        initWebview(mWebView)
}

其中webview加载中的网络请求 可以通过WebViewClient 来检测和处理到:

    inner class WebViewClient : android.webkit.WebViewClient() {

        override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
            return false
        }

        @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
        override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? {
            val url = request.url.toString()
            v("网页页面拦截:$url")
            //todo 这里可以针对一些请求做特殊处理
            return super.shouldInterceptRequest(view, request)
        }

        override fun onReceivedSslError(view: WebView, handler: SslErrorHandler, error: SslError?) {
            handler.proceed() // Ignore SSL certificate errors
        }

        override fun onPageStarted(view: WebView, url: String?, favicon: Bitmap?) {
            super.onPageStarted(view, url, favicon)
            v("网页页面开始加载:$url")
//            injectCustomFontCss(view)
        }

        override fun onPageFinished(view: WebView, url: String) {
            v("网页页面加载完成:$url")
            if (isLoadError && isInterrupt) {
                v("拦截的网页请求出错,加载错误页面")
                handleError()
                isLoadError = false
                return
            }
            if(!isLoadError) {
                title = view.title
                isLoadError = isTitleError(title)
            }
            if (isLoadError) {
                return
            } else {
                if (mOnUrlLoadFinishListener != null) {
                    mOnUrlLoadFinishListener!!.onUrlLoadFinish(url)
                }
            }
            try {
                view.loadUrl("javascript:onPageFinished();")
            }catch (e: Exception) {
                v("javascript:onPageFinished()  error:$e.toString()")
            }
            super.onPageFinished(view, url)
        }


        override fun onReceivedError(view: WebView?, errorCode: Int, description: String?, failingUrl: String?) {
            super.onReceivedError(view, errorCode, description, failingUrl)
            e("onReceivedError: $errorCode,$description,$failingUrl")
            if ((failingUrl != null && failingUrl != view?.url && failingUrl != view?.originalUrl) /* not subresource error*/
                || (failingUrl == null && errorCode != -12) /*not bad url*/
                || errorCode == -1) { //当 errorCode = -1 且错误信息为 net::ERR_CACHE_MISS
                return
            }
            if (failingUrl != null && failingUrl == view?.url) {
                e("请求失败地址2:$failingUrl")
                isLoadError = true
                handleError()
            }
        }


        override fun doUpdateVisitedHistory(view: WebView, url: String, isReload: Boolean) {
            super.doUpdateVisitedHistory(view, url, isReload)
            if (needClearHistory) {
                v("清除历史记录")
                view.clearHistory()
            }
        }
    }

上述代码可以基本实现webview 的 stetho调试,可以试试.

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值