工具的選擇
1.Android Studio(可以看,可以調試)
2.understand (只適合看)
macbook pro基本上只有這兩款可以選擇,剛開始用了understand發現並不怎麼好使,也許是沒有使用習慣,我們在看源碼的時候,有一些過程肯定也是需要調試才知道某些方法執行的先後順序,所以我最終選擇了AS,原來的時候也用AS 2.3看過源碼,那時候下面一直再scan index,導致沒法正常調式.最新的AS 3.5沒有這個問題.
編譯
進到android源碼的目錄下執行:
make idegen && development/tools/idegen/idegen.sh
然後一般會報錯:
could not find jdk tools.jar at
/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/../lib/tools.jar
解決方法, vi ~/.bash_profile,在bash_profile裏面添加如下代碼:
export JAVA_HOME=$(/usr/libexec/java_home)
export PATH=$JAVA_HOME/bin:$PATH
export CLASS_PATH=$JAVA_HOME/lib
export ANDROID_JAVA_HOME=$JAVA_HOME
如果你的JAVA_HOME已經配置,設置最後一行即可.編譯完成之後,會生成
如上圖所示的三個文件.
導入到Android Studio
- 點擊菜單的open–>選擇源碼目錄,接下來需要等一會兒生成index
- 點擊Configure project structure ,配置如下:
可以把不常用不看的代碼在這裏可以先排除出去,紅色的都是沒有生成索引的
接下來就是設置Android源碼之間相互依賴關聯,而不是依賴其他第三方的jar包.這裏面需要注意的是,先ctrl+A,選中所以,反選最後兩個,delete刪除其他的即可.不要一個一個去刪.
最後:
到這裏面基本上就設置完成了.
開啓模擬器
source build/envsetup.sh
lunch
選擇編譯的版本,可點擊emulator
我們第一篇文章謝了,我這裏面編譯的是aosp_x86_64-eng,好了,模擬器就正常加載了,但是進入到模擬器裏面的時候,每次點擊設置都會FC,報一個wifi2p的一個錯誤,這個可以在AS的logcat裏面看到,最後google到答案,說是wifi的鍋.然後修改源碼:
修改com.android.settings.wfd.WifiDisplaySettings中的isAvailable方法,返回false.
public static boolean isAvailable(Context context) {
//加上這個會在模擬器上面報錯
// return context.getSystemService(Context.DISPLAY_SERVICE) != null
// && context.getSystemService(Context.WIFI_P2P_SERVICE) != null;
return false;
}
這樣改過之後再重新make,啓動模擬器,你會發現進到設置裏面不會FC了
開始調試
- 點擊Attach debugger to Android Process,你會看到如下:
然後就可以選擇一個進程進行調試了,但是如果你想調試系統的一些進程,這還是不夠的,因爲我們在編譯的時候,編譯的是aosp_x86_64-eng,不是帶-userdebug參數的,所以沒辦法調試,帶-userdebug參數的都是給真機使用的,我也是在選擇了一個編譯完成以後才發現模擬器竟然不能用…,當然你也可以自定義編譯配置,有興趣可以網上搜一下,我這裏改了一下代碼:
在ZygoteProcess類的startViaZygote方法中,
argsForZygote.add("--enable-jni-logging");
argsForZygote.add("--enable-safemode");
argsForZygote.add("--enable-jdwp");
argsForZygote.add("--enable-checkjni");
argsForZygote.add("--generate-debug-info");
argsForZygote.add("--always-jit");
argsForZygote.add("--native-debuggable");
argsForZygote.add("--java-debuggable");
argsForZygote.add("--enable-assert");
argsForZygote.add("--mount-external-default");
argsForZygote.add("--mount-external-write");
// if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {
// argsForZygote.add("--enable-jni-logging");
// }
// if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
// argsForZygote.add("--enable-safemode");
// }
// if ((debugFlags & Zygote.DEBUG_ENABLE_JDWP) != 0) {
// argsForZygote.add("--enable-jdwp");
// }
// if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
// argsForZygote.add("--enable-checkjni");
// }
// if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {
// argsForZygote.add("--generate-debug-info");
// }
// if ((debugFlags & Zygote.DEBUG_ALWAYS_JIT) != 0) {
// argsForZygote.add("--always-jit");
// }
// if ((debugFlags & Zygote.DEBUG_NATIVE_DEBUGGABLE) != 0) {
// argsForZygote.add("--native-debuggable");
// }
// if ((debugFlags & Zygote.DEBUG_JAVA_DEBUGGABLE) != 0) {
// argsForZygote.add("--java-debuggable");
// }
// if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
// argsForZygote.add("--enable-assert");
// }
// if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
// argsForZygote.add("--mount-external-default");
// } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
// argsForZygote.add("--mount-external-read");
// } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
// argsForZygote.add("--mount-external-write");
// }
我把所有debug參數都給添加了上去.重新編譯運行.最後就可以愉快的玩耍了.但是有一個問題就是,調試運行都沒問題了,但是我想調試一個app的啓動,發現這個好像有點困難,因爲在進程啓動以後才能attach,但是其他的生命週期的調試沒有任何問題.
接下來我會完整的分析App的啓動流程和Activity的啓動流程.