当前位置:首页 > 开发教程 > 手机开发 >

Stetho(Facebook出品)的使用(不能随时翻墙的伙伴们就先收藏吧..)

时间:2016-06-07 14:47 来源: 作者: 收藏

其实很早就想写博客了只是一直没动手,今天写博客倒也不算心血来潮。然而我绝对想不到的是,我的第一篇博客竟然会发在这儿:因为一直到半年前,我压根就没听说过csdn,平常翻看的书也无非就是专业(会计)相关或者小说。但这半年对我的改变真的太大了。如果说

前言

Chrome的Developer Tools对于WEB开发者来讲几乎是一个神器,而Chrome Store里也有无奇不有的插件,如果Chrome能调安卓应用应该是一件美好的事,而Facebook开源的一个工具Stetho让Chrome调试Android 应用不再是一个梦。安卓在调试时,有时候需要查看数据库,SharePreference等,而这个前提是必须root,另一方面,andoird的网络方面的抓包调试显得很困难,而这一切,Stetho都为我们轻轻松松地解决。除了使用android集成环境里的工具查看view树,使用Stetho也可以做到。

加入依赖包

整个测试过程,我们需要用到数据库, SharePreference,以及Http请求,为了避免重复造轮子,我们引入几个第三方库。 
ActiveAndroid 一个android的orm,用于数据库操作 
LessCode 一个工具库,整个库使用jquery风格函数 
Okhttp 一个http请求库,配合stetho完成测试 
开发环境使用android studio,对于ActiveAndroid,我们需要加入以下代码

<code class=" hljs bash" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Microsoft YaHei';font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">repositories {
    mavenCentral()
    maven { url <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"https://oss.sonatype.org/content/repositories/snapshots/"</span> }
}
compile <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">‘com.michaelpardo:activeandroid:3.1.0-SNAPSHOT‘</span></code>

而LessCode则加入

<code class=" hljs bash" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Microsoft YaHei';font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">compile <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">‘com.jayfeng.lesscode:lesscode-core:0.1.3‘</span></code>

再加入okhttp的依赖

<code class=" hljs bash" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Microsoft YaHei';font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">compile <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">‘com.squareup.okhttp:okhttp:2.3.0‘</span></code>

最后加入Stetho,由于是配合okhttp,所以还要加入Stetho-okhttp

<code class=" hljs bash" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Microsoft YaHei';font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">compile <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">‘com.facebook.stetho:stetho:1.1.0‘</span>
compile <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">‘com.facebook.stetho:stetho-okhttp:1.1.0‘</span>
</code>

初始化配置

由于需要进行网络请求,所以加入请求网络的权限

<code class=" hljs xml" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Microsoft YaHei';font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><<span class="hljs-title" style="box-sizing: border-box; padding: 0px;">uses-permission</span> <span class="hljs-attribute" style="box-sizing: border-box; padding: 0px;">android:name</span>=<span class="hljs-value" style="box-sizing: border-box; padding: 0px;">"android.permission.INTERNET"</span> /></code>

ActiveAndroid需要进行一些简单的配置操作才能操作数据库 
在application节点下加入如下代码,主要是配置数据库名字,版本等信息,其中cn.edu.zafu.stethodemo.model.Person是一个实体类,该类继承com.activeandroid.Model,完成数据库操作

<code class=" hljs haskell" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Microsoft YaHei';font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><meta-<span class="hljs-typedef" style="box-sizing: border-box; padding: 0px;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">data</span></span>
    android:name=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"AA_DB_NAME"</span>
    android:value=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"Stetho.db"</span> />
<meta-<span class="hljs-typedef" style="box-sizing: border-box; padding: 0px;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">data</span></span>
    android:name=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"AA_DB_VERSION"</span>
    android:value=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"1"</span> />
<meta-<span class="hljs-typedef" style="box-sizing: border-box; padding: 0px;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;"><span id="0_nwp" style="box-sizing: border-box; padding: 0px; width: auto; height: auto; float: none;"><a target=_blank target="_blank" id="0_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.phpapp_id=0&c=news&cf=1001&ch=0&di=128&fv=17&is_app=0&jk=8c3f8b4b20ea6e0f&k=data&k0=data&kdi0=0&luki=9&n=10&p=baidu&q=65035100_cpr&rb=0&rs=1&seller_id=1&sid=f6eea204b8b3f8c&ssp2=1&stid=0&t=tpclicked3_hc&tu=u1836545&u=http%3A%2F%2Fwww%2Ebubuko%2Ecom%2Finfodetail%2D779411%2Ehtml&urlid=0" style="color: rgb(51, 51, 51); text-decoration: none; box-sizing: border-box; padding: 0px;"><span style="box-sizing: border-box; padding: 0px; color: rgb(0, 0, 255); width: auto; height: auto;">data</span></a></span></span></span>
    android:name=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"AA_MODELS"</span>
    android:value=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"cn.edu.zafu.stethodemo.model.Person"</span> /></code>

新建一个App类,继承com.activeandroid.app.Application,重写onCreate方法,在里面完成Stetho的初始化工作。构建一个Builder并进行配置,最后初始化Stetho

<code class=" hljs avrasm" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Microsoft YaHei';font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Stetho<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box; padding: 0px;">.initialize</span>(
    Stetho<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box; padding: 0px;">.newInitializerBuilder</span>(this)
        <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box; padding: 0px;">.enableDumpapp</span>(
                Stetho<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box; padding: 0px;">.defaultDumperPluginsProvider</span>(this))
        <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box; padding: 0px;">.enableWebKitInspector</span>(
                Stetho<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box; padding: 0px;">.defaultInspectorModulesProvider</span>(this))
        <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box; padding: 0px;">.build</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box; padding: 0px;">;</span></code>

布局

布局界面过于简单,不贴代码了,主要是三个按钮,一个用于网络请求,一个写入数据到数据库,一个写入数据到SharePreference,最终界面如图所示。 
Stetho(Facebook出品)的使用(不能随时翻墙的伙伴们就先收藏吧..)

关键代码

数据库操作使用ActiveAndroid库显得特别简单,调用save方法即可保存

<code class=" hljs cs" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Microsoft YaHei';font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">void</span> <span class="hljs-title" style="box-sizing: border-box; padding: 0px;">writeToSqlite</span>() {
        Person person = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">new</span> Person();
        person.setName(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"Jake"</span>);
        person.setAge(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; padding: 0px;">19</span>);
        person.save();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box; padding: 0px;">//保存</span>

        ToastLess.$(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">this</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"save to Sqlite successfully!"</span>);
    }</code>

而SharePreference的操作则通过LessCode库写入,只需一句话

<code class=" hljs cs" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Microsoft YaHei';font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">void</span> <span class="hljs-title" style="box-sizing: border-box; padding: 0px;">writeToSharedPreference</span>() {
        SharedPreferenceLess.$put(getApplicationContext(), <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"name"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"StethoDemo"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box; padding: 0px;">//写入数据</span>
        SharedPreferenceLess.$put(getApplicationContext(), <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"version"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"v1.0.0"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box; padding: 0px;">//写入数据</span>
        ToastLess.$(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">this</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"save to SharedPreference successfully!"</span>);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box; padding: 0px;">//显示一个通知提示</span>
    }</code>

复杂点的代码在网络请求,但是okhttp已经为我们封装好了,直接调用就好了

<code class=" hljs java" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Microsoft YaHei';font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">void</span> <span class="hljs-title" style="box-sizing: border-box; padding: 0px;">getFromNetwork</span>() {
        OkHttpClient client = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">new</span> OkHttpClient();
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box; padding: 0px;">//下面这句话显得尤为重要,加入后才能拦截到http请求。</span>
        client.networkInterceptors().<span id="2_nwp" style="box-sizing: border-box; padding: 0px; width: auto; height: auto; float: none;"><a target=_blank target="_blank" id="2_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.phpapp_id=0&c=news&cf=1001&ch=0&di=128&fv=17&is_app=0&jk=8c3f8b4b20ea6e0f&k=add&k0=add&kdi0=0&luki=2&n=10&p=baidu&q=65035100_cpr&rb=0&rs=1&seller_id=1&sid=f6eea204b8b3f8c&ssp2=1&stid=0&t=tpclicked3_hc&tu=u1836545&u=http%3A%2F%2Fwww%2Ebubuko%2Ecom%2Finfodetail%2D779411%2Ehtml&urlid=0" style="color: rgb(51, 51, 51); text-decoration: none; box-sizing: border-box; padding: 0px;"><span style="box-sizing: border-box; padding: 0px; color: rgb(0, 0, 255); width: auto; height: auto;">add</span></a></span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">new</span> StethoInterceptor());
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box; padding: 0px;">//构建请求</span>
        Request request = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">new</span> Request.Builder()
                .url(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; padding: 0px;">"http://www.baidu.com"</span>)
                .build();
        Response response = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">null</span>;

        client.newCall(request).enqueue(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">new</span> Callback() {
            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; padding: 0px;">@Override</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">void</span> <span class="hljs-title" style="box-sizing: border-box; padding: 0px;">onFailure</span>(Request request, IOException e) {

            }
            <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; padding: 0px;">@Override</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">void</span> <span class="hljs-title" style="box-sizing: border-box; padding: 0px;">onResponse</span>(Response response) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">throws</span> IOException {
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box; padding: 0px;">//此方法在子线程中,所以通过发送至handler处理</span>
                String body = response.body().string();
                Message message = handler.obtainMessage();
                message.what=NETWORK;
                message.obj=body;
                handler.sendMessage(message);
            }
        });
    }</code>

代码差不多就是这个样子了,剩下的就是如何进行调试了

使用Chrome调试

在我们运行完程序后,我们打开Chrome,在地址栏输入chrome://inspect/,我们会看到这样一个界面 
Stetho(Facebook出品)的使用(不能随时翻墙的伙伴们就先收藏吧..)

我们点击图中的蓝色inspect即可进入调试界面,如果点击该链接后你打开的是一个空白页面,那么恭喜你,你已经被GFW拦截了,你不得不进行翻墙,翻墙方法自己研究,这里我使用的时VPN。

打开该链接后,我们选中Elements,呈现在眼前的是这样一个界面。 
Stetho(Facebook出品)的使用(不能随时翻墙的伙伴们就先收藏吧..)

图片最左边是一棵当前界面的View树,当你选中一部分内容后,界面上对应的内容会高亮显示,如图右边的网络请求Button ,被一层蓝色遮罩,中间部分是当前选中的控件的一些属性。

现在我们切换至NetWork选项卡,然后点击模拟器中的第一个按钮,你会发现网络请求出现在了这个选项卡里,就像web调试一样。里面可以看到请求头信息,响应信息,Cookie等 
Stetho(Facebook出品)的使用(不能随时翻墙的伙伴们就先收藏吧..)

我们切换至Resources选项卡,在这里,我们能对数据库,SharedPreference等进行查看,先来看下数据库中的信息,一开始应该是空的信息,当我们点击模拟器中的第三个按钮,点击两次后,数据库中应该会新增两条记录,如图所示

Stetho(Facebook出品)的使用(不能随时翻墙的伙伴们就先收藏吧..)

此外,我们还可以进行sql语句操作,如图所示

Stetho(Facebook出品)的使用(不能随时翻墙的伙伴们就先收藏吧..)

当我们点击模拟器中的第二个按钮,应该会增加SharedPreference信息,就像图中所示

Stetho(Facebook出品)的使用(不能随时翻墙的伙伴们就先收藏吧..)

对应这个SharedPreference,其实可以通过Dumpapp进行修改,这里先放一张截图效果,后文解释,图中打印了SharedPreference中值,进行修改后再次打印 
Stetho(Facebook出品)的使用(不能随时翻墙的伙伴们就先收藏吧..)

由上面的一些功能看出,Stetho是如此强大,而这一切,无需手机Root,即使在没有root的真机上,这些信息也一览无余。

自定义dumpapp 插件

自定义插件是扩展dumpapp系统的首选方式,可以轻松地添加在配置。它的配置步骤是这样的:

<code class=" hljs java" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Microsoft YaHei';font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Stetho.initialize(Stetho.newInitializerBuilder(context)
    .enableDumpapp(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">new</span> MyDumperPluginsProvider(context))
    .build())

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">static</span> <span class="hljs-class" style="box-sizing: border-box; padding: 0px;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); padding: 0px;">MyDumperPluginsProvider</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">implements</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); padding: 0px;">DumperPluginsProvider</span> {</span>
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">public</span> Iterable<DumperPlugin> <span class="hljs-title" style="box-sizing: border-box; padding: 0px;">get</span>() {
    ArrayList<DumperPlugin> plugins = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">new</span> ArrayList<DumperPlugin>();
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">for</span> (DumperPlugin defaultPlugin :
        Stetho.defaultDumperPluginsProvider(mContext).get()) {
      plugins.<span id="1_nwp" style="box-sizing: border-box; padding: 0px; width: auto; height: auto; float: none;"><a target=_blank target="_blank" id="1_nwl" href="http://cpro.baidu.com/cpro/ui/uijs.phpapp_id=0&c=news&cf=1001&ch=0&di=128&fv=17&is_app=0&jk=8c3f8b4b20ea6e0f&k=add&k0=add&kdi0=0&luki=2&n=10&p=baidu&q=65035100_cpr&rb=0&rs=1&seller_id=1&sid=f6eea204b8b3f8c&ssp2=1&stid=0&t=tpclicked3_hc&tu=u1836545&u=http%3A%2F%2Fwww%2Ebubuko%2Ecom%2Finfodetail%2D779411%2Ehtml&urlid=0" style="color: rgb(51, 51, 51); text-decoration: none; box-sizing: border-box; padding: 0px;"><span style="box-sizing: border-box; padding: 0px; color: rgb(0, 0, 255); width: auto; height: auto;">add</span></a></span>(defaultPlugin);
    }
    plugins.add(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">new</span> MyDumperPlugin());
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; padding: 0px;">return</span> plugins;
  }
}</code>

至于MyDumperPlugin的编写,可以参考官方的写法,插件的使用是与dumpapp工具结合的,而上文中的dumpapp只是截了一张图,却没有解释如何使用,其实该插件位于官方项目的scripts目录下,该目录中的文件如图所示

Stetho(Facebook出品)的使用(不能随时翻墙的伙伴们就先收藏吧..)

从图中看到,没有windows下的执行文件,这几个文件应该是linux下或者mac下执行的,windows下式执行不了的,在linux下使用是极其简单的,只要将其加入环境变量,使用dumpapp –help命令即可查看使用说明,本文不在赘述,有兴趣的同学可以参考本文最后的两个链接进行摸索。

源码下载

http://download.csdn.net/detail/sbsujjbcy/8652377

相关地址

第一个是youtube上的一个全面介绍Stetho的视频,第二个是官方网站,有需要的可以参考。


手机开发阅读排行

最新文章