文章目录

  • 工具的选择
  • 编译
  • 导入到Android Studio
  • 开启模拟器
  • 开始调试


工具的选择

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已经配置,设置最后一行即可.编译完成之后,会生成

mac Androidstudio配置dart sdk path_Android

如上图所示的三个文件.

导入到Android Studio

  • 点击菜单的open–>选择源码目录,接下来需要等一会儿生成index
  • 点击Configure project structure ,配置如下:

可以把不常用不看的代码在这里可以先排除出去,红色的都是没有生成索引的

mac Androidstudio配置dart sdk path_java_02

接下来就是设置Android源码之间相互依赖关联,而不是依赖其他第三方的jar包.这里面需要注意的是,先ctrl+A,选中所以,反选最后两个,delete删除其他的即可.不要一个一个去删.

mac Androidstudio配置dart sdk path_Android_03

最后:

mac Androidstudio配置dart sdk path_Android_04

到这里面基本上就设置完成了.

开启模拟器

  1. source build/envsetup.sh
  2. lunchemulator

我们第一篇文章谢了,我这里面编译的是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了

开始调试

  1. 点击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的启动流程.