android 调试技巧汇总

目录:
chrome远程调试android webview
解决Hierarchy Viewer无法使用的问题
查看当前正在显示的activity
用对象的toString() 确定代码运行时某个interface的具体实现类是哪个.
快捷方式使用上一条命令的输出结果
ubuntu下用sqliteman图形化读数据库的数据
android studio 搜索时忽略R.java这样的生成文件, 提高查找关键字的效率
在log中快速定位crash的位置
善用android studio的Design窗口, 快速定位控件.
把log写入sdcard
对Log文件按Tag进行过滤, 方便进一步分析
对log中的关键字高亮显示
解决traceview find 功能无法使用的问题, 同样可以实现对framework API的监控
adb logcat只看Error Level的log
Android Studio Lifecycle Sorter 插件
统计应用占用的内存,以及其他占用系统资源的统计
使用pidcat
5步完成向github提交代码
使用APIMonitor
使用在线UML工具,对数据结构进行总结.
用Astah画UML图
使用adb bugreport监测耗电情况
使用dump View Hierarchy for UI automator快速定位界面上某个view的id
混淆后的类名需要到build服务器下载mapping.txt去映射到对应的原始类名
在native C++文件中添加log
定制app crash页面

=================================================

正文开始:
chrome远程调试android webview

step 1:
WebView mWebView;
mWebView = (WebView)findViewById(R.id.webView);
mWebView.setWebContentsDebuggingEnabled(true);
step 2:
PC chrome地址栏输入: chrome://inspect
可以很方便的对网页中的js打断点调试.

解决Hierarchy Viewer无法使用的问题

在代码中引入ViewServer这个类, 在注释中写的很明白.
对于工程机来说,不使用这个类也可以正常使用Hierarchy Viewer.

This class can be used to enable the use of HierarchyViewer inside an
 * application. HierarchyViewer is an Android SDK tool that can be used
 * to inspect and debug the user interface of running applications. For
 * security reasons, HierarchyViewer does not work on production builds
 * (for instance phones bought in store.) By using this class, you can
 * make HierarchyViewer work on any device. You must be very careful
 * however to only enable HierarchyViewer when debugging your
 * application.

chrome内核代码enable ViewServer的代码在AsyncInitializationActivity.java

if (CommandLine.getInstance().hasSwitch(ChromeSwitches.ENABLE_HIERARCHYVIEWER_DEBUG)) {
    mHierarchyViewDebug = true;
    ViewServer.get(this).addWindow(this);
}
查看当前正在显示的activity

adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'
修改 ~/.bashrc, 添加别名, 以后用自定义的adbwhichactivity就更方便了.

alias adbwhichactivity="adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'"

再定制一条命令: adbactivitytask 用于输出当前的activity task的信息.

alias adbactivitytask="adb shell dumpsys activity activities | sed -En -e '/Running activities/,/Run #0/p'"

用对象的toString() 确定代码运行时某个interface的具体实现类是哪个.
TabModel tabModel = Global.mBrowserActivity.getCurrentTabModel();

public TabModel getCurrentTabModel() {
  TabModelSelector modelSelector = getTabModelSelector();
  if (modelSelector == null) return EmptyTabModel.getInstance();
    return modelSelector.getCurrentModel();
}

TabModel是一个interface, 项目中有几个它的实现类, 为了跟踪在运行时具体的实现类是哪个,可以使用下面的debug方式.

BLog.i("ahking","SaveWebPagesActivity onStart() tabModel is: " + tabModel.toString());

Log 输出:

02-15 12:19:31.417  21208-21208/? I/ahking﹕ SaveWebPagesActivity onStart() tabModel is: org.chromium.chrome.browser.tabmodel.TabModelImpl@413bfa48

这样就确定了运行时具体的实现类是"TabModelImpl".

快捷方式使用上一条命令的输出结果

wangxin@wangxin:~/src/src/chrome/android$ findahking chrometabbedactivity.java
./java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
wangxin@wangxin:~/src/src/chrome/android$ vim `!!`

ubuntu下用sqliteman图形化读数据库的数据

sqliteman browser.db
把一个图片存入数据库的方法是把bitmap转换为byte[]数组, 然后以BLOB类型存入数据库,取出数据时, 再把byte[]数据转换为Bitmap.

Bitmap icon = currentTab.getFavicon();
ByteArrayOutputStream out = new ByteArrayOutputStream();
icon.compress(Bitmap.CompressFormat.PNG, 30, out);
values.put(SavePages.ICON, out.toByteArray());
Uri insert = getContentResolver().insert(SavePages.CONTENT_URI,values);
android studio 搜索时忽略R.java这样的生成文件, 提高查找关键字的效率

Define a custom scope to help you exclude intermediates files when searching.
follow "Ignore R.java fies in Find results"

在log中快速定位crash的位置

只需要搜"Shutting down VM" 关键字即可

04-07 14:53:05.698  24671-24671/com.qihoo.browser D/AndroidRuntime﹕ Shutting down VM
04-07 14:53:05.698  24671-24671/com.qihoo.browser W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41347ae0)
04-07 14:53:05.728  24671-24671/com.qihoo.browser E/AndroidRuntime﹕ FATAL EXCEPTION: main

或是再搜搜这个字符串.

E/AndroidRuntime(24434): FATAL EXCEPTION: main

可以再搜搜下面这个字符串.

thread exiting with uncaught exception
善用android studio的Design窗口, 快速定位控件.
android_studio_design.png

比原来单纯的从xml文本找控件的方式, 要更直观更快速, 可以多多使用提高效率.

把log写入sdcard

有些情况下,bug需要在release build下复现, 比如集成高德定位sdk, 安装debug包的手机因为key的原因会永远定位失败, 在这种情况下就需要把log写入sdcard, 进而分析定位失败的具体原因.

BLog.java
    public static void appendLog2SDCard(String text)
    {
        File logFile = new File("/sdcard/location.log");
        if (!logFile.exists())
        {
            try
            {
                logFile.createNewFile();
            }
            catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        try
        {
            //BufferedWriter for performance, true to set append to file flag
            BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
            buf.append(text);
            buf.newLine();
            buf.close();
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

用法:

BLog.appendLog2SDCard("LocationHelper onLocationChanged(), error_code = " + location.getAMapException().getErrorCode());
对Log文件按Tag进行过滤, 方便进一步分析

log.log是测试人员发过来的main log,过滤一下, 分析起来就更加清晰了.
实现了使用ultraedit过滤关键字一样的功能.
cat log.log | grep ahking > log2.log

// file: log2.log
I/ahking  (26744): ResourceExtractor doInBackgroundImpl()
I/ahking  (26744): ResourceExtractor doInBackgroundImpl() curTimeStampName = timestamp_10021_100.2.1_251
I/ahking  (26744): ResourceExtractor deleteFiles()
I/ahking  (26744): ResourceExtractor doInBackgroundImpl() appDataDir = /data/data/com.qihoo.browser/app_chrome
I/ahking  (26744): ResourceExtractor doInBackgroundImpl() file = chrome_100_percent.pak
I/ahking  (26744): =======================================================
I/ahking  (26744): ResourceExtractor doInBackgroundImpl() file = cloudurls.dat
I/ahking  (26744): =======================================================
I/ahking  (26744): ResourceExtractor doInBackgroundImpl() file = en-US.pak
I/ahking  (26744): =======================================================
I/ahking  (26744): ResourceExtractor doInBackgroundImpl() file = icudtl.dat
I/ahking  (26744): =======================================================
I/ahking  (26744): ResourceExtractor doInBackgroundImpl() file = natives_blob.bin
I/ahking  (26744): =======================================================
I/ahking  (26744): ResourceExtractor doInBackgroundImpl() file = resources.pak
I/ahking  (26744): =======================================================
I/ahking  (26744): ResourceExtractor doInBackgroundImpl() file = snapshot_blob.bin
I/ahking  (26744): =======================================================
I/ahking  (26744): ResourceExtractor doInBackgroundImpl() file = zh-CN.pak
I/ahking  (26744): =======================================================
E/skia    (26923): SkFontMgr_Android ahking
对log中的关键字高亮显示

wangxin@wangxin:~/Downloads$ adb logcat -s DroidBox | grep --color -E 'http:'

V/DroidBox(23726): Ljava/net/URL;-><init>(Ljava/lang/String;=http://p.s.360.cn/pstat/plog.php)V
V/DroidBox(23726): Ljava/net/URL;-><init>(Ljava/lang/String;=http://m.yiche.com/?wt.mc_id=m360mz)V
V/DroidBox(23726): Ljava/net/URL;-><init>(Ljava/lang/String;=http://m.yiche.com/?wt.mc_id=m360mz)V
V/DroidBox(23726): Ljava/net/URL;-><init>(Ljava/lang/String;=http://news.m.yiche.com/others/20160715/1506625294.html)V
V/DroidBox(23726): Ljava/net/URL;-><init>(Ljava/lang/String;=http://news.m.yiche.com/others/20160715/1506625294.html)V
V/DroidBox(23726): Ljava/net/URL;-><init>(Ljava/lang/String;=http://p.s.360.cn/pstat/plog.php)V

refer:
http://explainshell.com/
http://antanas.veiverys.com/android-logcat-log-with-keyword-highlights/

解决traceview find 功能无法使用的问题, 同样可以实现对framework API的监控
wangxin@wangxin:~/Downloads/temp$ ~/tool/android-sdk-linux/tools/traceview ./startup.trace

直接在底部的"Find"窗口,搜索方法名"android/app/sharedpreferencesimpl$editorimpl
.commit"也可以监控到app对framework API的调用.
注意点:

  1. 直接点android device monitor工具的"start method profiling"按钮抓取trace log,底部的"Find"窗口不工作, 什么原因造成的不知道, 也就是说想用"Find"功能就必须用traceview加载本地*.trace 文件.
  2. "Find"的查找只支持小写, 不支持大写.

在/sdcard/目录下, 生成startup.trace文件.

android.os.Debug.startMethodTracing("startup");
android.os.Debug.stopMethodTracing();
adb logcat只看Error Level的log
adb logcat | grep '^E'
Android Studio Lifecycle Sorter 插件

按照生命周期的调用前后顺序把代码重新排序, 阅读起来更加的方便.
另外, 观察Structure window, 里面的几个小细节的button使用起来对阅读代码也是很有帮助的.
eg. show non-public, show fields, 可以对当前文件有个快速的概括性的了解.
还是要多写代码, 多实践, 从中可以发现不少提高开发效率的小技巧, 不能只停留在口头和只学习不去实践.

统计应用占用的内存,以及其他占用系统资源的统计
wangxin@wangxin:~/Downloads/log/Logs_2.1_20160825_141742$ adb shell dumpsys meminfo com.qihoo.browser
Applications Memory Usage (kB):
Uptime: 700089526 Realtime: 1812746797

** MEMINFO in pid 32398 [com.qihoo.browser] **
                         Shared  Private     Heap     Heap     Heap
                   Pss    Dirty    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------
       Native       20        8       20    23264    18663     1552
       Dalvik    30717     4332    30632    27364    22734     4630
       Cursor        4        0        4                           
       Ashmem        0        0        0                           
    Other dev     8638    10508     3408                           
     .so mmap    10826     1956     3592                           
    .jar mmap        0        0        0                           
    .apk mmap     1010        0        0                           
    .ttf mmap      520        0        0                           
    .dex mmap     6682        0     1084                           
   Other mmap     1730       12      488                           
      Unknown    14713      464    14712                           
        TOTAL    74860    17280    53940    50628    41397     6182
 
 Objects
               Views:      473         ViewRootImpl:        3
         AppContexts:        8           Activities:        2
              Assets:        5        AssetManagers:        5
       Local Binders:       84        Proxy Binders:       33
    Death Recipients:        3
     OpenSSL Sockets:        0
 
 SQL
         MEMORY_USED:      252
  PAGECACHE_OVERFLOW:       45          MALLOC_SIZE:       62
 
 DATABASES
      pgsz     dbsz   Lookaside(b)          cache  Dbname
         4       24            414        95/31/8  /data/data/com.qihoo.browser/databases/downloads.db
         4      124             91         6/26/3  /data/data/com.qihoo.browser/databases/browser.db
使用pidcat

彩色输出log信息, 看起来清新多了.

gedit ~/.bashrc

添加一条

alias pidcatbrowser="/home/wangxin/src/github/pidcat-master/pidcat.py com.qihoo.browser"

以后使用pidcatbrowser命令就可以了.

5步完成向github提交代码
github:
AandK.wangxin2011@gmail.com
830202**

refer to : http://my.oschina.net/apeng/blog/109945

wangxin@wangxin:~/src/github/StrictANR$ 
git init
git add .
git commit -m "first commit"
git remote add origin https://github.com/AandK/StrictANR.git
git push -u origin master 

代码更新:

git status
git add app/src/main/java/com/github/strictanr/testapp/MainActivity.java app/src/main/java/com/github/strictanr/testapp/StrictANRTestApplication.java app/src/main/java/com/github/strictanr/util/StrictANRWatchDog.java app/src/main/res/layout/activity_main.xml
git commit -m "toast a message when strict anr detected"
git push -u origin master 
使用APIMonitor
cd /home/wangxin/Downloads/temp/APIMonitor-beta
vim ./config/default_api_collection
./apimonitor.py chrome-debug.apk 
adb install chrome-debug_new.apk 
pidcatbrowser
使用在线UML工具,对数据结构进行总结.

genmymodel online uml
AandK.wangxin2011@gmail.com
830202**
挺好用的, 就是导出图片功能要收费. 每月5美元, 还是别用了.

processon
国产的免费在线工具, 用微信登录.

用Astah画UML图

你是砍柴的, 他是放牛的.
在工作中, 还是应该放松心态, 抱着宽厚的心态和别人交流, 我找了不少时间的uml工具, 一直没有找到理想的, 突然想起来上次baosheng提到的日本人开发的Astah工具, 是真心的好用阿, 今天用它把数据结构的类图整理好了, 导出图片的功能也很好用.

wangxin@wangxin:~/tool/astah_community$ ./astah

文档保存在:

wangxin@wangxin:~/Documents$ ls
数据结构.asta
wangxin@wangxin:~/Documents$ 
使用adb bugreport监测耗电情况

refer to :
http://www.kancloud.cn/digest/itfootballprefermanc/100905
http://blog.csdn.net/baniel01/article/details/51954142

wangxin@wangxin:~/tool/battery/battery-historian-master/scripts$ adb shell dumpsys batterystats --enable full-wake-history
Enabled: full-wake-history
wangxin@wangxin:~/tool/battery/battery-historian-master/scripts$ adb shell dumpsys batterystats --reset
Battery stats reset.
//操作一段时间后//
wangxin@wangxin:~/tool/battery/battery-historian-master/scripts$ adb bugreport > bugreport.txt

//google的分析工具
wangxin@wangxin:~/tool/battery/battery-historian-master/scripts$ python historian.py -a bugreport.txt > battery.html

//sony的分析工具
wangxin@wangxin:~/tool/battery/battery-historian-master/scripts$ java -jar ~/Downloads/chkbugreport.jar ./bugreport.txt

用chrome打开生成的html文件, 图形化显示耗电情况.

Battery Historian还有一个2.0的版本, 更好用一些.
本地安装go环境,启动Battery Historian 2.0 web server, 但却无法加载本地文件,
找了一个 Battery Historian 2.0 在线分析工具
http://23.251.148.173/
可以使用.

使用dump View Hierarchy for UI automator快速定位界面上某个view的id

注意: 要使用android 6.0的手机才能显示view的id.

sony_4.2.2_ui.png
三星6.0.png
混淆后的类名需要到build服务器下载mapping.txt去映射到对应的原始类名

今天报过来一个ANR log, backtrace如下:

  at android.os.Environment.isExternalStorageRemovable(Environment.java:749)

  at java.lang.reflect.Method.invoke!(Native method)

  at com.a.bs.c(unavailable:-1)

  at com.a.bs.f(unavailable:-1)

  at com.a.bs.b(unavailable:-1)

但com.a.bs.b 是混淆后的类型和方法名, 项目代码中是搜不到的, 需要使用mapping.txt进行映射才能找到代码中对应的类.

com.loc.di -> com.a.bs:
    android.content.Context a -> a
    int b(java.lang.Object,java.lang.String,java.lang.Object[]) -> b

实际的位置是: 高德sdk AMap_Location_V2.4.0_20160308.jar中的di.class类.

package com.loc;
public class di {
...
}
在native C++文件中添加log

//添加native log in C++ file.

#include "base/logging.h"
LOG(WARNING) << "ahking log";

//编译 chromium

python runhooks_android.py
cd src/
ninja -C out/Release chrome_public_apk

//替换so库到android studio

wangxin@wangxin:~/src/src_chromium_begin/src$ cp ./out/Release/chrome_public_apk/libs/armeabi-v7a/libchrome_public.so ./chrome/android/java/libs/armeabi-v7a/libchrome_public.so

//log output:

12-12 15:11:42.042 23172-23172/com.qihoo.browser W/chromium: [WARNING:password_manager.cc(674)] ahking log, PasswordManager::AskUserOrSavePassword()
定制app crash页面

使用开源项目, 实际效果很不错, 比一个傻傻的crash dialog显示给用户, 要用户体验好的多.
https://github.com/Ereza/CustomActivityOnCrash

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,800评论 25 707
  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    passiontim阅读 15,412评论 2 45
  • 很多人在二十岁已经死了 只是八十岁才开始埋葬 每个人光鲜亮丽的身后 藏着多少不能说的腐朽 躯体里住着死去的灵魂 支...
    一只红薯阅读 190评论 0 1
  • 忽然不知道该给这篇乱作起什么名字,原本是准备看书的,拿起手机刷好久不玩的微博,发现一个奇怪的名字,在好奇心的驱使下...
    lulal阅读 165评论 0 0
  • 煮了面面,试着做些好吃的。独立生活过后,才渐渐体会到父母的不容易,那句话怎么说来着?好怕自己成长的速度追不上他们老...
    晒太阳919阅读 139评论 0 0