android调试stetho的那点事
Posted xjz729827161
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android调试stetho的那点事相关的知识,希望对你有一定的参考价值。
在调试安卓程序的过程中,受不了每次看日志查看网络的响应和导出db的动作(甚至有时候都无法导出db),这里安利一个facebook出品的神器 stetho,不过这个有些限制,在使用的时候一定的通过usb与调试的手机相连通的,也要使用chrome浏览器
1. stetho支持的功能
支持的功能主要是针对网络和db的,看github项目上的趋势,应该是在准备一些后续的功能(按照需求集成咯,我觉得网络和db的最重要了),把官网的介绍抠了下来官网stetho介绍
1. 支持应用的网络请求返回报文的查看
在chrome浏览器中输入chrome://inspect
来进入。(第一次使用这个功能的时候要翻墙,翻墙,翻墙,重要的事情要说三遍,不然你点击了inpect永远是空白的,如果没法翻墙,请查看这篇文章)
2. 支持的db查看功能 和 支持的sql语句直接进行交互功能(增删改查都是可以的)
2. 集成stetho
-
导入依赖
implementation ‘com.facebook.stetho:stetho:1.5.0’ -
根据网络请求框架导入不同的依赖包
implementation ‘com.facebook.stetho:stetho-okhttp3:1.5.0’
or:
implementation ‘com.facebook.stetho:stetho-urlconnection:1.5.0’ -
在application中进行集成
public class MyApplication extends Application
public void onCreate()
super.onCreate();
Stetho.initializeWithDefaults(this);
- 如果是有网络请求的,以okhttp举例,创建okhttpClient的时候需要加入一个拦截器
new OkHttpClient.Builder() .addNetworkInterceptor(new StethoInterceptor()) .build()
3. 集成stetho的建议(干货)
-
建立一个单独的productFlavor来集成功能,不要在正式的环境中集成这个东西。会使得应用变得更加庞大,也给应用留下漏洞
比如在build.gradle建立一个productflavorproductFlavors
在应用的的main目录中建立一个productFlavor innerteset的目录,然后把,通过清单合并操作中的替换application类的方式重新指定application.
-
关于网络的请求中,有的应用的报文是有加解密的。这里需要做一些额外的动作
修改默认的网络请求拦截类StethoInterceptor.class
,新建的一个类把原来的类文件中东西拷贝出来进行调整
解密请求的报文,主要是修改内部类OkHttpInspectorRequest
的body()
,拿到原始报文的,请求体,完成解密动作后重新包装生成一个请求体,给原来的代码使用。下面有一个我在自己应用中使用的实例@Nullable public byte[] body() throws IOException //我的测试应用的请求报文都是data:的格式,所以这里这么写,各个应用要按照自己应用的需求改写 FormBody copyedBody = (FormBody) (this.mRequest.body()); List<String> nameList = new ArrayList<>(); List<String> valusList = new ArrayList<>(); for (int i=0; i< copyedBody.size(); i++) nameList.add(copyedBody.encodedName(i)); if ("data".equals(copyedBody.encodedName(i))) valusList.add(new JsonFormatUtil().formart(这里解密请求的报文)); FormBody copyedBody2 = new FormBody.Builder().add(nameList.get(0), valusList.get(0)).build(); FormBody body = copyedBody2; //下面这块代码不动,保持原样,上面重新生成了requestBody而已 if (body == null) return null; else OutputStream out = this.mRequestBodyHelper.createBodySink(this.firstHeaderValue("Content-Encoding")); BufferedSink bufferedSink = Okio.buffer(Okio.sink(out)); try body.writeTo(bufferedSink); finally bufferedSink.close(); return this.mRequestBodyHelper.getDisplayBody();
解密返回报文,返回的报文,stetho是保存在文件中的然后进行的发送,需要修改默认的
ResponseHandler
抄袭原来的ReponseHanlder,主要修改的onEOF方式
//调整原来的类,增加一个readFile的方法 public void onEOF() this.reportDataReceived(); try readFile(this.mRequestId); catch (IOException e) Log.e(TAG, "readFile Exception onEOF: " + e); this.mEventReporter.responseReadFinished(this.mRequestId); //读取默认的文件 public ResponseBodyData readFile(String requestId) throws IOException ResponseBodyFileManager responseBodyFileManager = new ResponseBodyFileManager(CeshiApplication.getApplication()); ResponseBodyData responseBodyData = responseBodyFileManager.readFile(requestId); OutputStream outputStream = null; //这个对象是数据的对象,用于json转换使用 SfReponseBodyData sfReponseBodyData = new Gson().fromJson(responseBodyData.data, SfReponseBodyData.class); sfReponseBodyData.data = 这里就可以进行解密的动作,得到解密的字符串; try outputStream = responseBodyFileManager.openResponseBodyFile(requestId, responseBodyData.base64Encoded); String data = new Gson().toJson(sfReponseBodyData); data = data.replace("\\\\", ""); data = new JsonFormatUtil().formart(data); outputStream.write(data.getBytes()); catch (Exception e) Log.e(TAG, "readFile Exception: " + e); finally if (null != outputStream) outputStream.close(); LogUtils.getInstance().showLogD(TAG, "readFile" ,"new record"); return null;
为了在浏览器上好看,报文最后都需要进行格式化,比如我这里是默认的json报文,就进行格式化后传给浏览器
//网络上随便抠的一段格式代码
public class JsonFormatUtil
public String formart(String s)
int level = 0;
//存放格式化的json字符串
StringBuilder jsonForMatStr = new StringBuilder();
for (int index = 0; index < s.length(); index++)//将字符串中的字符逐个按行输出
//获取s中的每个字符
char c = s.charAt(index);
//level大于0并且jsonForMatStr中的最后一个字符为\\n,jsonForMatStr加入\\t
if (level > 0 && '\\n' == jsonForMatStr.charAt(jsonForMatStr.length() - 1))
jsonForMatStr.append(getLevelStr(level));
//遇到""和"["要增加空格和换行,遇到""和"]"要减少空格,以对应,遇到","要换行
switch (c)
case '':
case '[':
jsonForMatStr.append(c + "\\n");
level++;
break;
case ',':
jsonForMatStr.append(c + "\\n");
break;
case '':
case ']':
jsonForMatStr.append("\\n");
level--;
jsonForMatStr.append(getLevelStr(level));
jsonForMatStr.append(c);
break;
default:
jsonForMatStr.append(c);
break;
return jsonForMatStr.toString();
private static String getLevelStr(int level)
StringBuilder levelStr = new StringBuilder();
for (int levelI = 0; levelI < level; levelI++)
levelStr.append("\\t");
return levelStr.toString();
以上是关于android调试stetho的那点事的主要内容,如果未能解决你的问题,请参考以下文章