目錄:
chrome遠(yuǎn)程調(diào)試android webview
解決Hierarchy Viewer無(wú)法使用的問(wèn)題
查看當(dāng)前正在顯示的activity
用對(duì)象的toString() 確定代碼運(yùn)行時(shí)某個(gè)interface的具體實(shí)現(xiàn)類(lèi)是哪個(gè).
快捷方式使用上一條命令的輸出結(jié)果
ubuntu下用sqliteman圖形化讀數(shù)據(jù)庫(kù)的數(shù)據(jù)
android studio 搜索時(shí)忽略R.java這樣的生成文件统屈, 提高查找關(guān)鍵字的效率
在log中快速定位crash的位置
善用android studio的Design窗口许昨, 快速定位控件.
把log寫(xiě)入sdcard
對(duì)Log文件按Tag進(jìn)行過(guò)濾革答, 方便進(jìn)一步分析
對(duì)log中的關(guān)鍵字高亮顯示
解決traceview find 功能無(wú)法使用的問(wèn)題, 同樣可以實(shí)現(xiàn)對(duì)framework API的監(jiān)控
adb logcat只看Error Level的log
Android Studio Lifecycle Sorter 插件
統(tǒng)計(jì)應(yīng)用占用的內(nèi)存,以及其他占用系統(tǒng)資源的統(tǒng)計(jì)
使用pidcat
5步完成向github提交代碼
使用APIMonitor
使用在線UML工具禾唁,對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行總結(jié).
用Astah畫(huà)UML圖
使用adb bugreport監(jiān)測(cè)耗電情況
使用dump View Hierarchy for UI automator快速定位界面上某個(gè)view的id
混淆后的類(lèi)名需要到build服務(wù)器下載mapping.txt去映射到對(duì)應(yīng)的原始類(lèi)名
在native C++文件中添加log
定制app crash頁(yè)面
=================================================
正文開(kāi)始:
chrome遠(yuǎn)程調(diào)試android webview
step 1:
WebView mWebView;
mWebView = (WebView)findViewById(R.id.webView);
mWebView.setWebContentsDebuggingEnabled(true);
step 2:
PC chrome地址欄輸入: chrome://inspect
可以很方便的對(duì)網(wǎng)頁(yè)中的js打斷點(diǎn)調(diào)試.
解決Hierarchy Viewer無(wú)法使用的問(wèn)題
在代碼中引入ViewServer這個(gè)類(lèi)拙绊, 在注釋中寫(xiě)的很明白.
對(duì)于工程機(jī)來(lái)說(shuō),不使用這個(gè)類(lèi)也可以正常使用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內(nèi)核代碼enable ViewServer的代碼在AsyncInitializationActivity.java
if (CommandLine.getInstance().hasSwitch(ChromeSwitches.ENABLE_HIERARCHYVIEWER_DEBUG)) {
mHierarchyViewDebug = true;
ViewServer.get(this).addWindow(this);
}
查看當(dāng)前正在顯示的activity
adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'
修改 ~/.bashrc, 添加別名, 以后用自定義的adbwhichactivity就更方便了.
alias adbwhichactivity="adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'"
再定制一條命令: adbactivitytask 用于輸出當(dāng)前的activity task的信息.
alias adbactivitytask="adb shell dumpsys activity activities | sed -En -e '/Running activities/,/Run #0/p'"
用對(duì)象的toString() 確定代碼運(yùn)行時(shí)某個(gè)interface的具體實(shí)現(xiàn)類(lèi)是哪個(gè).
TabModel tabModel = Global.mBrowserActivity.getCurrentTabModel();
public TabModel getCurrentTabModel() {
TabModelSelector modelSelector = getTabModelSelector();
if (modelSelector == null) return EmptyTabModel.getInstance();
return modelSelector.getCurrentModel();
}
TabModel是一個(gè)interface, 項(xiàng)目中有幾個(gè)它的實(shí)現(xiàn)類(lèi)枢希, 為了跟蹤在運(yùn)行時(shí)具體的實(shí)現(xiàn)類(lèi)是哪個(gè)桌吃,可以使用下面的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
這樣就確定了運(yùn)行時(shí)具體的實(shí)現(xiàn)類(lèi)是"TabModelImpl".
快捷方式使用上一條命令的輸出結(jié)果
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圖形化讀數(shù)據(jù)庫(kù)的數(shù)據(jù)
sqliteman browser.db
把一個(gè)圖片存入數(shù)據(jù)庫(kù)的方法是把bitmap轉(zhuǎn)換為byte[]數(shù)組, 然后以BLOB類(lèi)型存入數(shù)據(jù)庫(kù)苞轿,取出數(shù)據(jù)時(shí)茅诱, 再把byte[]數(shù)據(jù)轉(zhuǎn)換為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 搜索時(shí)忽略R.java這樣的生成文件逗物, 提高查找關(guān)鍵字的效率
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" 關(guān)鍵字即可
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
或是再搜搜這個(gè)字符串.
E/AndroidRuntime(24434): FATAL EXCEPTION: main
可以再搜搜下面這個(gè)字符串.
thread exiting with uncaught exception
善用android studio的Design窗口, 快速定位控件.
比原來(lái)單純的從xml文本找控件的方式瑟俭, 要更直觀更快速翎卓, 可以多多使用提高效率.
把log寫(xiě)入sdcard
有些情況下,bug需要在release build下復(fù)現(xiàn)摆寄, 比如集成高德定位sdk失暴, 安裝debug包的手機(jī)因?yàn)閗ey的原因會(huì)永遠(yuǎn)定位失敗, 在這種情況下就需要把log寫(xiě)入sdcard微饥, 進(jìn)而分析定位失敗的具體原因.
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());
對(duì)Log文件按Tag進(jìn)行過(guò)濾逗扒, 方便進(jìn)一步分析
log.log是測(cè)試人員發(fā)過(guò)來(lái)的main log,過(guò)濾一下欠橘, 分析起來(lái)就更加清晰了.
實(shí)現(xiàn)了使用ultraedit過(guò)濾關(guān)鍵字一樣的功能.
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
對(duì)log中的關(guān)鍵字高亮顯示
wangxin@wangxin:~/Downloads$ adb logcat -s DroidBox | grep --color -E 'http:'
V/DroidBox(23726): Ljava/net/URL;-><init>(Ljava/lang/String;=http://p.s.#/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.#/pstat/plog.php)V
refer:
http://explainshell.com/
http://antanas.veiverys.com/android-logcat-log-with-keyword-highlights/
解決traceview find 功能無(wú)法使用的問(wèn)題, 同樣可以實(shí)現(xiàn)對(duì)framework API的監(jiān)控
wangxin@wangxin:~/Downloads/temp$ ~/tool/android-sdk-linux/tools/traceview ./startup.trace
直接在底部的"Find"窗口矩肩,搜索方法名"android/app/sharedpreferencesimpl$editorimpl
.commit"也可以監(jiān)控到app對(duì)framework API的調(diào)用.
注意點(diǎn):
- 直接點(diǎn)android device monitor工具的"start method profiling"按鈕抓取trace log,底部的"Find"窗口不工作肃续, 什么原因造成的不知道黍檩, 也就是說(shuō)想用"Find"功能就必須用traceview加載本地*.trace 文件.
- "Find"的查找只支持小寫(xiě), 不支持大寫(xiě).
在/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 插件
按照生命周期的調(diào)用前后順序把代碼重新排序刽酱, 閱讀起來(lái)更加的方便.
另外, 觀察Structure window, 里面的幾個(gè)小細(xì)節(jié)的button使用起來(lái)對(duì)閱讀代碼也是很有幫助的.
eg. show non-public, show fields, 可以對(duì)當(dāng)前文件有個(gè)快速的概括性的了解.
還是要多寫(xiě)代碼疼蛾, 多實(shí)踐肛跌, 從中可以發(fā)現(xiàn)不少提高開(kāi)發(fā)效率的小技巧, 不能只停留在口頭和只學(xué)習(xí)不去實(shí)踐.
統(tǒng)計(jì)應(yīng)用占用的內(nèi)存,以及其他占用系統(tǒng)資源的統(tǒng)計(jì)
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信息艺配, 看起來(lái)清新多了.
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工具察郁,對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行總結(jié).
genmymodel online uml
AandK.wangxin2011@gmail.com
830202**
挺好用的, 就是導(dǎo)出圖片功能要收費(fèi). 每月5美元转唉, 還是別用了.
processon
國(guó)產(chǎn)的免費(fèi)在線工具皮钠, 用微信登錄.
用Astah畫(huà)UML圖
你是砍柴的, 他是放牛的.
在工作中赠法, 還是應(yīng)該放松心態(tài)麦轰, 抱著寬厚的心態(tài)和別人交流, 我找了不少時(shí)間的uml工具砖织, 一直沒(méi)有找到理想的款侵, 突然想起來(lái)上次baosheng提到的日本人開(kāi)發(fā)的Astah工具, 是真心的好用阿侧纯, 今天用它把數(shù)據(jù)結(jié)構(gòu)的類(lèi)圖整理好了新锈, 導(dǎo)出圖片的功能也很好用.
wangxin@wangxin:~/tool/astah_community$ ./astah
文檔保存在:
wangxin@wangxin:~/Documents$ ls
數(shù)據(jù)結(jié)構(gòu).asta
wangxin@wangxin:~/Documents$
使用adb bugreport監(jiān)測(cè)耗電情況
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.
//操作一段時(shí)間后//
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打開(kāi)生成的html文件, 圖形化顯示耗電情況.
Battery Historian還有一個(gè)2.0的版本眶熬, 更好用一些.
本地安裝go環(huán)境妹笆,啟動(dòng)Battery Historian 2.0 web server, 但卻無(wú)法加載本地文件块请,
找了一個(gè) Battery Historian 2.0 在線分析工具
http://23.251.148.173/
可以使用.
使用dump View Hierarchy for UI automator快速定位界面上某個(gè)view的id
注意: 要使用android 6.0的手機(jī)才能顯示view的id.
混淆后的類(lèi)名需要到build服務(wù)器下載mapping.txt去映射到對(duì)應(yīng)的原始類(lèi)名
今天報(bào)過(guò)來(lái)一個(gè)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 是混淆后的類(lèi)型和方法名, 項(xiàng)目代碼中是搜不到的, 需要使用mapping.txt進(jìn)行映射才能找到代碼中對(duì)應(yīng)的類(lèi).
com.loc.di -> com.a.bs:
android.content.Context a -> a
int b(java.lang.Object,java.lang.String,java.lang.Object[]) -> b
實(shí)際的位置是: 高德sdk AMap_Location_V2.4.0_20160308.jar中的di.class類(lèi).
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庫(kù)到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頁(yè)面
使用開(kāi)源項(xiàng)目拳缠, 實(shí)際效果很不錯(cuò)墩新, 比一個(gè)傻傻的crash dialog顯示給用戶, 要用戶體驗(yàn)好的多.
https://github.com/Ereza/CustomActivityOnCrash