在Android Studio中使用com.facebook.stetho:stetho
库来通过Chrome的开发者工具调试HTTP请求和响应以及H5页面(即Web内容),需要几个步骤来配置和启用Stetho。这里我将详细介绍如何在Android应用中进行设置。
1. 添加依赖
首先,确保在你的build.gradle
(通常是app模块的)文件中添加了stetho
和stetho-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中访问你的应用:
- 打开Chrome浏览器。
- 访问
chrome://inspect
。 - 你应该能在Devices部分看到你的设备,点击它。
- 在出现的列表中,找到你的应用,点击
inspect
链接。 - 这将打开一个新的开发者工具窗口,你可以在这里查看网络请求、资源、控制台日志等,就像你在调试一个网页一样。
注意事项
- 确保你的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调试,可以试试.