(Android源码)掌握Android阅读源码的两种简单方式 | 您所在的位置:网站首页 › 如何查看安卓app源码 › (Android源码)掌握Android阅读源码的两种简单方式 |
学习背景
最近在看《Android开发艺术探索》书籍,想突破一下自己知识的瓶颈,发现书中有许多知识都结合的源码进行讲解的。源码是我一直很畏惧的区域,很多时候遇到问题在网上搜索解决方式时,遇到长篇大论说源码的,我就会看不下去。如果想让我的技术得到进阶,那就必须得慢慢地区尝试阅读它,最终希望可以通过阅读源码发现或解决实际中遇到的问题。 阅读源码的方式这里只提供网上比较常见的简单的阅读方式,网上也有许多关于下载与编译源码相关文章,由于我只需要满足阅读的要求,就不做过多的研究。 拓展内容: 以下几个是下载源码过程比较完整的文章: Android官方源码下载的地址及教程 Android版本的平台代号、标记和Build号 下载AOSP android源码(最小最快下载方式,跳过编译直接导入Android Studio) Ubuntu 16.04 在线阅读源码 - AndroidXRef这种方式操作简单,效率高。 进入网站: AndroidXRef以下部分参考: AndroidXRef的帮助文档 在线看Android系统源码,那些相见恨晚的几种方案 界面右侧: 提供在特定目录下搜索,例如在分析 Framework源码时,可以选择 frameworks 目录,这样可以减少搜索范围,缩短搜索时间,能够更加精确地定位到需要的源代码。 界面左侧: 提供了一些搜索的条件,其意义如下(在指定的 Project(s)下): 字段 作用 Full Search 全文搜索,搜索索引中的所有文本标记(单词,字符串,标识符,数字)。搜索符号:覆盖符号的定义及使用,包括注释出现该符号 。 Definition 仅查找符号定义。例如搜索xx函数在哪些类中有定义。 Symbol 仅查找符号。包括该符号的定义及使用位置。 File Path 源文件的路径。搜索源码文件名中包含给定字符串的文件。(类级别)支持输入类名等。方法名通过前三种方式搜索! History 历史记录日志注释。上述的符号:可以是代表你要搜索的内容,如变量、方法、类等。以上仅是个人理解。 使用流程: graph LR id1(界面左边在特定字段输入关键字)-->id2(界面右边选择特定目录,不确定select all即可) id2-->id3(点击search)以搜索ActivityThread#handleLaunchActivity的方法为例:在查看handleLaunchActivity()这个方法在哪里定义的 在 Definition 中输入handleLaunchActivity搜索 ActivityThread 就可以了。 以上只是单个搜索,还支持多条件搜索,需要更高级的搜索语法。 请参考:Opengrok搜索帮助 在Android Studio中阅读源码其实最开始,我了解的阅读源码的方式是Android提供的SDK里面的源码包。以android29为例 资源准备保证你的SDK有以下两个文件目录: sdk路径/platforms/android-xxx :该文件夹下存放不同版本的Android系统。 sdk路径/sources/android-xxx:该文件夹下存放了Android的源代码。如果没有该如何下载? platforms的下载: Android Studio 中下载 Tools——SDK Manager——Android SDK /SDK Platforms——选择你要下载的版本并apply即可 直接下载 platforms/android-28 | platforms/android-29sources下载: Android Studio 中下载 Tools——SDK Manager——Android SDK /SDK Platforms——底部选中show package detail——可以看到是否选择了 sources for Android xxx,如果没有选择并apply即可下载。 直接下载 sources/android-28 | sources/android-29 搜索引擎搜索说明:xxx表示android的版本。(对应项目build.gradle中 compileSdkVersion: 29) compileSdkVersion是编译所依赖的Android SDK的版本。更多SDK目录含义介绍参考:Android SDK目录含义介绍 资源准备好了,接下来打开项目,以Activity为例,选中 mac 快捷键 command+B(或者command+鼠标左键), 是不是这样就完成了呢?有没有发现很多类都爆红,点击进去没有反应,导致看到关键的时候,无法看下去了,为什么呢? 搜索引擎一下原因: 总结:是Google公司由于安全和稳定等因素考虑,部分源码是不对外开放的。 需要注意的是 @hide 参考:听说 Android 9.0 要禁用 @Hide Api 的调用,你怎么看? @hide 方法众所周知,Android 系统在迭代的过程中,越来越重视安全这个因素。而有一些方法可能会涉及到系统安全、用户隐私或者其他一些原>因,总之有一些因素考量,在发布出来的时候,被 Google 标记为 @hide,表示并不希望开发者去使用它们。 而这些标记为 @hide 的方法,我们也是无法直接调用的,只能使用反射的方式去调用它们,这本身就是不安全的操作。 不过呢,我们有时候确实为了实现一些功能,需要使用到这些被标记为 @hide 的方法。 解决方式: 启发文章:AndroidStudio下阅读源码的正确姿势 总结一下这篇文章的结论,将 SDK location/platforms/android-xxx/android.jar 和 framework.jar结合在一起生成新的android.jar。这个jar可以在开发中使用Android的内部/隐藏API。 具体流程: 参考:android-hidden-api SDK location/platforms/android-xxx 将下载对应api版本修改后的android.jar,粘贴并替换到该目录中,例如android-29/android.jar。 最后,Android Studio中ReBuild你的项目。 遇到的问题: 在android-hidden-api中下载指定的api的android.jar替换后,gradle编译不通过,提示如下: > Task :app:lint FAILED Calling mockable JAR artifact transform to create file: /home/user/.gradle/caches/transforms-1/files-1.1/android.jar/7470a0577854d0dc407ece72235e8952/android.jar with input /home/rgordeev/Android/Sdk/platforms/android-28/android.jar FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:lint'. > Could not resolve all files for configuration ':app:androidApis'. > Failed to transform file 'android.jar' to match attributes {artifactType=android-mockable-jar, returnDefaultValues=false} using transform MockableJarTransform > java.lang.IllegalArgumentException (no error message) 导致的原因: 在issue#46 Android Studio 3.2.0 sync error: Failed to transform android.jar有解释: Android Studio 版本 3.1.4 、Gradle 4.6 使用所提供的28以下的android.jar 貌似没问题,如果Android版本过高,则需要利用其它的方式来生成android.jar。自定义android.jar 具体请看android-jar-with-hidden-api利用aosp(Android Open-Source Project。"Android 开放源代码项目"。)源码来生成可访问AOSP隐藏API的android.jar 解决方式: 直接使用别人通过源码生成的android.jar 直接下载 android-28/android.jar | android-29/android.jar 替换 rebuild项目即可。现在再到Activity源码看: 通过AndroidStudio调试阅读源码,发现调试进入行号与自己的sdk/sources的不一致,还会出现行号跑到注释里去的问题。 解决方式 Debugger/Frames里可以看到调用到哪些方法,即可以知道这一步进入的是哪个方法,通过Command+F快捷键在对应的源码类中搜索方法名即可定位到正确的位置。这样虽然可以找到正确的方法的行号,但是并没有实际解决问题。 网上搜索了一下,总结几点原因: 使用真机调试,因为很大部分国产手机可能对源码进行了修改。 使用的compileSdkVersion版本(编译所依赖的Android SDK的版本,对应 sdk/platforms/android-xxx)与模拟器的运行的API版本不一致。 使用非官方模拟器,比如我用了genymotion模拟器,同样是api29,compileSdkVersion版本也是29,但是仍会出现行号不一致问题,切换回官方的模拟器,行号就一致了。 |
CopyRight 2018-2019 实验室设备网 版权所有 |