tomgarden / tom-notes Goto Github PK
View Code? Open in Web Editor NEW📒 手写板 , 每一篇文字会对应生成一个 Issues , 在 Issues 里可以互动 .
📒 手写板 , 每一篇文字会对应生成一个 Issues , 在 Issues 里可以互动 .
;*.cc
从代码阅读中我们间歇性记录的一点小细节。
关键文件:android-4.4.4_r1\dalvik\libdex\DexFile.h
Dex 文件结构 |
---|
DexHeader |
/*
* These match the definitions in the VM specification.
unit*_t : * 代表 bit(位) uint8_t 代表无符号整数所占内存为 1字节(8bit)
u* 或者 s* : * 代表字节 u1 说明,u1 所表示的数据所占内存为 1字节。
*/
typedef uint8_t u1;
typedef uint16_t u2;
typedef uint32_t u4;
typedef uint64_t u8;
typedef int8_t s1;
typedef int16_t s2;
typedef int32_t s4;
typedef int64_t s8;
/*
* Direct-mapped "header_item" struct.
*/
struct DexHeader {
u1 magic[8]; /* includes version number */
u4 checksum; /* adler32 checksum */
u1 signature[kSHA1DigestLen]; /* SHA-1 hash */
u4 fileSize; /* length of entire file */
u4 headerSize; /* offset to start of next section */
u4 endianTag;
u4 linkSize;
u4 linkOff;
u4 mapOff;
u4 stringIdsSize;
u4 stringIdsOff;
u4 typeIdsSize;
u4 typeIdsOff;
u4 protoIdsSize;
u4 protoIdsOff;
u4 fieldIdsSize;
u4 fieldIdsOff;
u4 methodIdsSize;
u4 methodIdsOff;
u4 classDefsSize;
u4 classDefsOff;
u4 dataSize;
u4 dataOff;
};
对于符合规范的 DEX 文件来说:
前四字节代表#define DEX_MAGIC "dex\n"
后四字节有两种可能
#define DEX_MAGIC_VERS "036\0"
#define DEX_MAGIC_VERS_API_13 "035\0"
用表格表示:
API\Byte Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
API(13,+∞) | d | e | x | \n | 0 | 3 | 6 | \0 |
API(-∞,13] | d | e | x | \n | 0 | 3 | 5 | \0 |
以前用 SourceInsight 做这件事 , 需要安装虚拟机 , 现在用 AndroidStudio
查看 自己 检出的 Android 源代码版本 > 方式一 :
/build/core/version_defaults.mk
打开version_defaults.mk 文件,然后找� PLATFORM_SDK_VERSION
这个关键字的值,就可以在下表中找出相应的版本。如何生成AndroidStudio可以打开的项目文件
development/tools/idegen/readme
中有讲如何操作,我们按照其步骤来即可。未提前编译 AOSP 源码同步完成后支架操作 idegen 生成 android.ipr 尝试导入源码 , 点击无法跳转
先make development/tools/idegen/子目录:
mmm development/tools/idegen/
cd development/tools/idegen/
mmm
生成项目文件:
development/tools/idegen/idegen.sh
idegen.ipr
和 idegen.iml
将项目导入到 idea 或者 AndroidStudio
idegen.ipr
父目录(AOSP 目录)即可idegen.ipr
文件即可IDEA 配置修改
如果 时间太久(2020-07-16 09:56:50) 还是应该参照官方指导做出合适的配置 aosp/development/tools/idegen/README
个人配置如下 :
//Help -> Edit custom properties
# 支持文件数
idea.max.intellisense.filesize=100000
# 支持大小写
idea.case.sensitive.fs=true
//Help > Edit Custom VM
-Xms1g
-Xmx5g
ipr
文件省心, 要忍受相对较陈旧的 IDE 工具
查看 idegen.sh 文件的 git 提交时间 , 找到历史 idea(2016.3.8
或 2017.3.7
) 版本进行导入 ,
观察到 :
虽然有些许红色错误提示 , 但是可以顺利完成 Java 跳转
不支持 Kotlin (思路二 可以知道为啥不支持 kotlin)
要完成 java 跳转需要做的额外事情是:
File -> Project Structure
窗口Project Settings
中的 Modules
子项Dependencies
标签<Module source>
和 <No SDK>
移动到列表顶部仍然要先安装软件执行导入/打开动作
导入后先完成如下动作 , 在 2017 版本如下操作尝到了甜头在 2020 版本仍然保持这个做法
File -> Project Structure
窗口Project Settings
中的 Modules
子项Dependencies
标签<Module source>
和 <No SDK>
移动到列表顶部新思路 : 要使用 idea 2018 、 2019 或者 2020 版本我们或需是需要研究下 idea 的 .iml
文件
通过测试我们知道
iml
文件 , 再通过修改查看索引结果将 .iml
文件中的 <sourceFolder
节点中的属性 type
及其对应的值删掉并且重新扫描和建立索引的话就可以完成 java 代码跳转了
type="kotlin-test"
和 type="kotlin-source"
iml
文件中 content
节点本身就没有 kotlin
代码所在的路径的配置iml
文件格式如下
<!--非本次重点的头部信息略-->
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<!--自定义节点用于控制 kotlin 跳转 , 可以手动添加 , 觉得手动添加烦人 , 就写个脚本吧 , 找出所有需要添加的路径一次完成-->
<!--[猜测 , 未测试]也可以通过 `File -> Project Structure` 添加节点-->
<sourceFolder url="file://$MODULE_DIR$/tools/metalava/src/test/java" />
<!--原来的content 内容 删除了 sourceFolder 节点中的 type 属性-->
<sourceFolder url="file://$MODULE_DIR$/art/test/004-JniTest/src" />
<!--content 中的其他节点省略-->
</content>
<!--orderEntry 节点们 也省略-->
</component>
</module>
至此我们已经可以通过 idea 正常读取 AOSP 了
事实上 : 通过 Android Studio 也可行
仍然会有部分错误提示 , 暂时放一放这个细节
//=================== 一个失败的分割线 ===================
{
"last_success_opt_commit_log_line_key": "0cf499714fdecc4e7e2cfa21914f6c0e3ed48e61···@/@···2024-03-30 13:03:14 +0800···@/@···nooon",
"issues_dictionary_map_key": {
"README.md": 2,
"Collection/Android/Android系统源代码情景分析/AOSP/OS_Build.md": 3,
"Collection/Android/Android系统源代码情景分析/AOSP/OS_Read_sources.md": 4,
"Collection/Android/Android系统源代码情景分析/AOSP/OS_Source_download-1.md": 5,
"Collection/Android/Android系统源代码情景分析/AOSP/OS_Source_download.md": 6,
"Collection/Android/Android系统源代码情景分析/AOSP/快捷链接.md": 7,
"Collection/Android/Gradle/GitHub_Packages_了解.md": 8,
"Collection/Android/Android系统源代码情景分析/AOSP/OS_Debug.md": 9,
"Collection/Android/Android系统源代码情景分析/AOSP/OS_Run_emulator.md": 10,
"Collection/Android/Gradle/gradle探索方向.md": 11,
"Collection/Android/性能优化/AndroidAPP质量评价标准.md": 12,
"Collection/Android/性能优化/AndroidProfiler.md": 13,
"Collection/Android/性能优化/ReadMe.md": 14,
"Collection/Android/性能优化/systrace.md": 15,
"Collection/kotlin/clone.md": 16,
"Collection/QAS/C++/spawn-fcgi包装app异常文件疑问.md": 17,
"Collection/QAS/C++/群组.md": 18,
"_posts/Collections/Android/ASO/ASO预研.md": 19,
"_posts/Collections/Android/AndroidStudio/AndroidStudio方便使用.md": 20,
"_posts/Collections/Android/AndroidStudio/kotlin自动注释.md": 21,
"_posts/Collections/Android/AndroidStudio/log/2018-08-07-log-1.md": 22,
"_posts/Collections/Android/AndroidStudio/下载 ndk .md": 23,
"_posts/Collections/Android/AndroidStudio/修改默认路径配置.md": 24,
"_posts/Collections/Android/AndroidStudio/异常处理.md": 25,
"_posts/Collections/Android/Android_API_DOC/2018-08-09-\tandroid.util.Log.md": 26,
"_posts/Collections/Android/Android_API_DOC/android.net/ConnectivityManager.md": 27,
"_posts/Collections/Android/Android_API_DOC/android.os.Build.md": 28,
"_posts/Collections/Android/Android_API_DOC/android.provider/android.provider.CallLog.md": 29,
"_posts/Collections/Android/Android系统源代码情景分析/AOSP/Handler-Looper-Message.md": 30,
"_posts/Collections/Android/Android系统源代码情景分析/AOSP/OS_Logger_module.md": 31,
"_posts/Collections/Android/Android系统源代码情景分析/AOSP/OS_Read_pakcage_understand.md": 33,
"_posts/Collections/Android/Android系统源代码情景分析/AOSP阅读工具.md/AndroidStudio或IntelliJ.md": 34,
"_posts/Collections/Android/Android系统源代码情景分析/AOSP阅读工具.md/SourceInside.md": 35,
"_posts/Collections/Android/Android系统源代码情景分析/Dex文件结构/Dex文件结构-1.md": 36,
"_posts/Collections/Android/Android系统源代码情景分析/Dex文件结构/Reference.md": 37,
"_posts/Collections/Android/Android系统源代码情景分析/README.md": 38,
"_posts/Collections/Android/Android系统源代码情景分析/list/list.md": 39,
"_posts/Collections/Android/Android系统源代码情景分析/todo.md": 40,
"_posts/Collections/Android/Android系统源代码情景分析/一些学习资源.md": 41,
"_posts/Collections/Android/Android系统源代码情景分析/助力硬件.md": 42,
"_posts/Collections/Android/Android系统源代码情景分析/必须做的事情.md": 43,
"_posts/Collections/Android/Android系统源代码情景分析/方法小计/1.md": 44,
"_posts/Collections/Android/Android系统源代码情景分析/方法小计/c-c++语法.md": 45,
"_posts/Collections/Android/Android系统源代码情景分析/方法小计/words.md": 46,
"_posts/Collections/Android/Android系统源代码情景分析/方法小计/调用栈/2018-3-23.md": 47,
"_posts/Collections/Android/Android系统源代码情景分析/点/一点思考.md": 48,
"_posts/Collections/Android/Android系统源代码情景分析/点/关键服务的源码位置.md": 49,
"_posts/Collections/Android/Android系统源代码情景分析/目录/11章-Zygote和System进程的启动过程.md": 50,
"_posts/Collections/Android/Android系统源代码情景分析/阻碍/1-AndroidStudio入手.md": 51,
"_posts/Collections/Android/Android系统源代码情景分析/阻碍/2-SourceInsight入手.md": 52,
"_posts/Collections/Android/Android系统源代码情景分析/阻碍/3-.aidl转.java.md": 53,
"_posts/Collections/Android/Android系统源代码情景分析/阻碍/4-编译源代码.md": 54,
"_posts/Collections/Android/Drozer/drozer 使用方法.md": 55,
"_posts/Collections/Android/Drozer/drozer-下载-安装-资源.md": 56,
"_posts/Collections/Android/Drozer/drozer按需把控.md": 57,
"_posts/Collections/Android/Gesture/1临渊羡鱼.md": 58,
"_posts/Collections/Android/Gradle/Gradle.Error.md": 59,
"_posts/Collections/Android/Gradle/README.md": 60,
"_posts/Collections/Android/Gradle/一个窗口打开多个Project.md": 61,
"_posts/Collections/Android/Gradle/代理设置.md": 62,
"_posts/Collections/Android/Gradle/内存占用.md": 63,
"_posts/Collections/Android/Gradle/编译速度.md": 64,
"_posts/Collections/Android/Intent/Intent_1.md": 65,
"_posts/Collections/Android/Intent/Intent_2.md": 66,
"_posts/Collections/Android/JetPack.md": 67,
"_posts/Collections/Android/Library/PermissionUtil/2018-10-20_readme.md": 68,
"_posts/Collections/Android/Library/PermissionUtil/Java.lang.ClassNotFoundException.md": 69,
"_posts/Collections/Android/Library/PermissionUtil/Permission.md": 70,
"_posts/Collections/Android/Security/信息源.md": 71,
"_posts/Collections/Android/Uri/使用 String 生成 Uri 的常见操作.md": 72,
"_posts/Collections/Android/Utils/Overview.md": 73,
"_posts/Collections/Android/Utils/app_permission.md": 74,
"_posts/Collections/Android/aapt/1_aapt.md": 75,
"_posts/Collections/Android/adb/README.md": 76,
"_posts/Collections/Android/adb/adb_shell_dumpsys.md": 77,
"_posts/Collections/Android/adb/adb按需探索.md": 78,
"_posts/Collections/Android/adb/adb整体把控.md": 79,
"_posts/Collections/Android/adb/logcat.md": 80,
"_posts/Collections/Android/android_os/android-环境变量.md": 81,
"_posts/Collections/Android/apktool/1_apktool.md": 82,
"_posts/Collections/Android/clone_app/clone app.md": 83,
"_posts/Collections/Android/custom weight/View 加载流程 & 自定义控件.md": 84,
"_posts/Collections/Android/custom weight/custom Preference.md": 85,
"_posts/Collections/Android/find_view_by_id.md": 86,
"_posts/Collections/Android/ndk/ndk-build_error_collection.md": 87,
"_posts/Collections/Android/point4dev/AndroidBarStatus.md": 88,
"_posts/Collections/Android/point4dev/AndroidTest/Android测试探究.md": 89,
"_posts/Collections/Android/point4dev/Android性能分析.md/Android性能分析-1.md": 90,
"_posts/Collections/Android/point4dev/Android性能分析.md/内存泄露.md": 91,
"_posts/Collections/Android/point4dev/Android性能分析.md/卡顿和丢帧问题分析.md": 92,
"_posts/Collections/Android/point4dev/Application_Performance_Management(APM)/Application_Performance_Management(APM).md": 93,
"_posts/Collections/Android/point4dev/DataBinding.md": 94,
"_posts/Collections/Android/point4dev/Google Play 发布 app.md": 95,
"_posts/Collections/Android/point4dev/HTTPDNS.md": 96,
"_posts/Collections/Android/point4dev/Handler-Message-MessageQueue-Looper.md": 97,
"_posts/Collections/C_C++/知识点/NULL & nullptr & 0.md": 98,
"_posts/Collections/C_C++/知识点/POSIX.md": 99,
"_posts/Collections/C_C++/知识点/define & typedef .md": 100,
"_posts/Collections/C_C++/知识点/delete-free-malloc.md": 101,
"_posts/Collections/C_C++/知识点/gdb/gdb_感性.md": 102,
"_posts/Collections/C_C++/知识点/gdb/gdb_理性.md": 103,
"_posts/Collections/C_C++/知识点/include.md": 104,
"_posts/Collections/C_C++/知识点/question/question_1.md": 105,
"_posts/Collections/C_C++/知识点/作用域.md": 106,
"_posts/Collections/C_C++/知识点/关于指针.md": 107,
"_posts/Collections/C_C++/知识点/关键字/extern.md": 108,
"_posts/Collections/C_C++/知识点/内存对齐&页对齐.md": 109,
"_posts/Collections/C_C++/知识点/内存管理.md": 110,
"_posts/Collections/C_C++/知识点/动态库 & 静态库.md": 111,
"_posts/Collections/C_C++/知识点/变量初始化.md": 112,
"_posts/Collections/C_C++/知识点/名词解释_1.md": 113,
"_posts/Collections/C_C++/知识点/名词解释_2.md": 114,
"_posts/Collections/C_C++/知识点/命名空间.md": 115,
"_posts/Collections/C_C++/知识点/头文件 & 命名空间.md": 116,
"_posts/Collections/C_C++/知识点/头文件 & 类 & 成员变量.md": 117,
"_posts/Collections/C_C++/知识点/字节序.md": 118,
"_posts/Collections/C_C++/知识点/小技巧.md": 119,
"_posts/Collections/C_C++/知识点/析构函数(Destructor).md": 120,
"_posts/Collections/C_C++/知识点/标准库/标准库小结_1.md": 121,
"_posts/Collections/C_C++/知识点/现象.md": 122,
"_posts/Collections/C_C++/知识点/空字符.md": 123,
"_posts/Collections/C_C++/知识点/编译器-标准库.md": 124,
"_posts/Collections/C_C++/知识点/编译错误/warning.md": 125,
"_posts/Collections/C_C++/知识点/跨平台/跨平台-2.md": 126,
"_posts/Collections/C_C++/知识点/跨平台/跨平台.md": 127,
"_posts/Collections/C_C++/知识点/预处理/#ifndef,#define,#endif.md": 128,
"_posts/Collections/C_C++/知识点/预处理/预处理.md": 129,
"_posts/Collections/C_C++/知识点/预处理/预处理`##`.md": 130,
"_posts/Collections/Cryptorarphy/AES.md": 131,
"_posts/Collections/Cryptorarphy/RSA算法.md": 132,
"_posts/Collections/DesignPattern/DesignPrinciple.md": 133,
"_posts/Collections/DesignPattern/FactoryPattern.md": 134,
"_posts/Collections/Doxygen.md": 135,
"_posts/Collections/Flutter/README.MD": 136,
"_posts/Collections/GIT/.gitignore.md": 137,
"_posts/Collections/GIT/GitHub/2018-08-14-GraphQL API v4.md": 138,
"_posts/Collections/GIT/GitHub/2018-08-14-REST API v3 [Overview].md": 139,
"_posts/Collections/GIT/GitHub/2018-08-15-Apps.md": 140,
"_posts/Collections/GIT/GitHub/2018-08-15-REST API v3 [Issue].md": 141,
"_posts/Collections/GIT/GitHub/2018-08-18-REST API v3 [OAuth Authorizations API].md": 142,
"_posts/Collections/GIT/GitHub/2018-08-20-REST API v3 [search].md": 143,
"_posts/Collections/GIT/GitHub开发者计划.md": 144,
"_posts/Collections/GIT/README.MD": 145,
"_posts/Collections/GIT/git diff.md": 146,
"_posts/Collections/GIT/git remote.md": 147,
"_posts/Collections/GIT/git-差异化配置.md": 148,
"_posts/Collections/GIT/git_operate.md": 149,
"_posts/Collections/GIT/man/git branch --help.md": 150,
"_posts/Collections/GIT/访问 github 连接被拒绝.md": 151,
"_posts/Collections/I know , I don't know/Android/Android Linux 命令.md": 152,
"_posts/Collections/I know , I don't know/Android/Android源码阅读.md": 153,
"_posts/Collections/I know , I don't know/Android/编程.md": 154,
"_posts/Collections/I know , I don't know/C++/c++类定义时,关键字class和类名之间还有一个宏.md": 155,
"_posts/Collections/I know , I don't know/Linux可执行文件.md": 156,
"_posts/Collections/I know , I don't know/int取值范围.md": 157,
"_posts/Collections/I know , I don't know/makefile.md": 158,
"_posts/Collections/IOS/IOS逆向.md": 159,
"_posts/Collections/IOS/_问题贴.md": 160,
"_posts/Collections/IOS/关于测试.md": 161,
"_posts/Collections/IOS/关于越狱.md": 162,
"_posts/Collections/IOS/杂记.md": 163,
"_posts/Collections/IOS/越狱之后文件传输.md": 164,
"_posts/Collections/Internet/(Ramnode)购买了一个VPS.md": 165,
"_posts/Collections/Internet/IPv6.md": 166,
"_posts/Collections/Internet/InitVerticalPrivateRoom.md": 167,
"_posts/Collections/Internet/InstallShadowsocks.md": 168,
"_posts/Collections/Internet/Linux方向键乱码.md": 169,
"_posts/Collections/Internet/Ramnode体验.md": 170,
"_posts/Collections/Internet/TCP-IP--Http--Socket.md": 171,
"_posts/Collections/Internet/VPS_选购_存档.md": 172,
"_posts/Collections/Internet/VPS测试工具.md": 173,
"_posts/Collections/Internet/perl_warning_Setting_locale_failed.引发的问题.md": 174,
"_posts/Collections/Internet/计算机网络.md": 175,
"_posts/Collections/Java/JNI/JNI 学习资料.md": 176,
"_posts/Collections/Java/JNI/JNI.1.md": 177,
"_posts/Collections/Android/未分类/架构&模式.md": 178,
"_posts/Collections/Android/未分类/Handler.md": 179,
"_posts/Collections/Android/未分类/JetPack.md": 180,
"_posts/Collections/Android/面经&八股/Android Basic Activity.md": 181,
"_posts/Collections/Android/面经&八股/Android Basic Intent.md": 182,
"_posts/Collections/Android/面经&八股/Android Basic View.md": 183,
"_posts/Collections/Android/面经&八股/Android Basic.md": 184,
"_posts/Collections/Android/面经&八股/ReadMe.MD": 185,
"_posts/Collections/关于学习方法/关于-陈皓.md": 186,
"_posts/Collections/Android/Android系统源代码情景分析/AOSP/1.下载源代码.md": 187,
"_posts/Collections/Software/jdk提取免安装文件.md": 189,
"_posts/Collections/Android/Android系统源代码情景分析/AOSP/2.下载源代码.ubuntu18.md": 190,
"_posts/Collections/Android/Android系统源代码情景分析/AOSP/3.Ubuntu多版本OpenJDK.md": 191,
"_posts/Collections/Android/Android系统源代码情景分析/AOSP/OS_Read_sources.md": 192,
"_posts/Collections/Android/Gradle/GitHub_Packages_了解.md": 193,
"_posts/Collections/Android/Gradle/Maven_centrol_了解.md": 194,
"_posts/Collections/Android/未分类/Android监控库.md": 195,
"_posts/Collections/Android/未分类/查看Android项目依赖关系.md": 196,
"_posts/Collections/Software/Editor/VIM个人配置.md": 197,
"_posts/Collections/Software/Postman.md": 198,
"_posts/Collections/Software/docker/0_docker_compose.md": 199,
"_posts/Collections/Software/nginx_笔记.md": 200,
"_posts/Collections/Software/ssh_秘钥登录远程服务器.md": 201,
"_posts/Collections/Web/Java/2_Spring.md": 202,
"_posts/Collections/Web/Java/Spring With MongoDb.md": 203,
"_posts/Collections/Web/Java/Spring 国际化.md": 204,
"_posts/Collections/Web/Java/Spring_learn_1.md": 205,
"_posts/Collections/Web/Java/Spring琐碎的收集知识点.md": 206,
"_posts/Collections/Web/MongoDB/1_mongodb.md": 207,
"_posts/Collections/Web/前端/1_Readme.md": 208,
"_posts/Collections/Web/前端/2_实际问题考量.md": 209,
"_posts/Collections/Web/前端/3_webpack.md": 210,
"_posts/Collections/Web/前端/html/debug.md": 211,
"_posts/Collections/Web/前端/kotlin-js/1_了解.md": 212,
"_posts/Collections/Web/前端/npm/npm_breakpoint_debug.md": 213,
"_posts/Collections/Web/前端/react/0_React-了解.md": 214,
"_posts/Collections/Web/前端/react/2_国际化.md": 215,
"_posts/Collections/Web/前端/react/3_如何组织一个项目.md": 216,
"_posts/Collections/Web/前端/react/4_路由.md": 217,
"_posts/Collections/Web/前端/react/5_以正式环境构建并启动前端代码.md": 218,
"_posts/Collections/Web/前端/react/6_刷新时候变量丢失.md": 219,
"_posts/Collections/Web/前端/react/mui/1_MUI 相关的细节语法.md": 220,
"_posts/Collections/Web/前端/script/1_JavaScript.understand.md": 221,
"_posts/Collections/Web/前端/script/2_TypeScript.md": 222,
"_posts/Collections/Web/前端/script/3_浏览器提供哪些API.md": 223,
"_posts/Collections/关于学习方法/.md": 224,
"_posts/Collections/Web/运维/1.md": 225,
"_posts/Collections/Operations/Linux/Ubuntu/Software/Ubuntu小工具.md": 226,
"_posts/Collections/Android/Gradle/_1_learn.md": 227,
"_posts/Collections/Software/rime-输入法.md": 228
}
}
DexClassLoader(String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent)
{@code File.pathSeparator}
分隔代表待加载文件路径的变量 (jar/apk){@code File.pathSeparator}
分隔代表待加载文件路径的变量 (native)但凡想要进行一些细节操作的时候都会因为对 Android 系统的一些操作不了解而感到困惑 .
目的 : 这次是在完善 lib_pickcolor 的时候 , DialogFragment 的状态保存不知道怎么保存函数参数(kotlin) ,
但是 SDK 提供的 AlertDialog 却是可以保存部分自己的按钮实现代码的 , 所以想模仿它 , 又无从下手 ,
所以就再次来到 AOSP 了 .
路线 : 从 App 启动入手 , 这样的话能预见到的重点为:
嗯 , 日拱一卒
我们的代码版本(编译虚拟机的版本和源代码的版本是相同的)
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=10
TARGET_PRODUCT=aosp_x86
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_ARCH=x86
TARGET_ARCH_VARIANT=x86
HOST_ARCH=x86_64
HOST_OS=darwin
HOST_OS_EXTRA=Darwin-19.5.0-x86_64-10.15.5
HOST_BUILD_TYPE=release
BUILD_ID=QQ3A.200605.002.A1
OUT_DIR=out
============================================
当看到 Launcher.java 一个文件 2000+ 行代码 , 我就告诉自己我一定不能傻傻的一行一行读 ,
这一小节可以先跳过, 后面碰到困难的时候可以回来寻找对应的细节
大致脉络如下 , 看代码的时候参考这个脉络自然是清晰的
//aosp/frameworks/base/core/java/android/app/Instrumentation.java
int result = ActivityTaskManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
IActivityTaskManager.aidl
文件在 IPC C/S 架构中的 server 端实现代码就是我们要寻找的目标
IActivityTaskManager.Stub
类extends IActivityTaskManager.Stub
,startActivity
的调用细节 .aosp/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
ActivityTaskManagerService
需要针对进程 system_process
, 而不是应用进程略
从图中吸收吧
在这一部分存疑的问题 , 在真正触发新进程创建之前的判断逻辑跟进暂未完成 ,
因为如果无需新建进程的情况下 , 是不会触发后续流程的 .
startSpecificActivityLocked:1008, ActivityStackSupervisor (com.android.server.wm)
resumeTopActivityInnerLocked:3040, ActivityStack (com.android.server.wm)
resumeTopActivityUncheckedLocked:2578, ActivityStack (com.android.server.wm)
resumeFocusedStacksTopActivities:1159, RootActivityContainer (com.android.server.wm)
completePauseLocked:1843, ActivityStack (com.android.server.wm)
activityPausedLocked:1770, ActivityStack (com.android.server.wm)
handleMessage:455, ActivityStack$ActivityStackHandler (com.android.server.wm)
dispatchMessage:107, Handler (android.os)
loop:214, Looper (android.os)
run:67, HandlerThread (android.os)
run:44, ServiceThread (com.android.server)
ActivityTaskManagerService.startActivity
ActivityTaskManagerService.activityPaused
现在需要跟进的是 startActivity 如何触发 activityPaused 动作
了解 startActivity 更多细节查看是否有触发 activityPaused 的动作
如果在这里是在找不到还有一个思路 , 更深入的理解 Binder 看看通信更深入的细节或需有帮助
创建新 Task 的时候也做了应用和系统进程间的 binder 通信
找到了 哇哈哈哈哈哈 , 通过 Binder 通信告知 Launcher 暂停自身
进程间通信流程固然重要, 厘清各个进程内部的线程间通信也十分必要 ,
尤其是 System-process 进程中的线程间通信
感觉上有一个 Handler 在做循环等待 Client 做部分修正
ActivityTaskManagerService.startActivity 在断点的调试的时候会有多次调用 , 需要理解
至此我们可以继续下一步跟进动作了
Process.start(...)
断点发现调用栈是来自ServiceThread
-> HandlrThread
-> Looper
-> 略sendMessage(message.setCallback(...))
的调用注意力来到 ActivityStack 了
能监控的启动调用流程中没有找到 ActivityStack 相关的可以联想的内容 , 暂时还是考虑 Handler 通信吧
ActivityStack$ActivityStackHandler 这个类重点观察下相关内容
有了实质性的进展现在需要搞清楚的点如下
RootActivityContainer.resumeFocusedStacksTopActivities
被调用两次这件事需要继续跟进 ,ActivityTaskManagerService$startActivty
> 此调度入口可以探寻ActivityTaskManagerService$activityPaused
> 此调度入口暂时未知ActivityTaskManagerService$activityPaused
的调度入口, 但仍然可以跟进下这个流程
DONE - 下一步是需要辨析 ClientLifecycleManager 对象中的函数调用差异以及在客户端进程中的细节差异
下一步重新编译 framework
- 循环节点已经完成插桩
- 记得先解决可能发生的异常再编译 , 预计使用部分编译动作
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ Thread: Binder:1819_11
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ Binder.execTransact (Binder.java:994)
│ Binder.execTransactInternal (Binder.java:1021)
│ IActivityTaskManager$Stub.onTransact (IActivityTaskManager.java:1981)
│ ActivityTaskManagerService.activityPaused (ActivityTaskManagerService.java:1714)
│ ActivityStack.activityPausedLocked (ActivityStack.java:1769)
│ ActivityStack.completePauseLocked (ActivityStack.java:1842)
│ RootActivityContainer.resumeFocusedStacksTopActivities (RootActivityContainer.java:1161)
│ ActivityStack.resumeTopActivityUncheckedLocked (ActivityStack.java:2577)
│ ActivityStack.resumeTopActivityInnerLocked (ActivityStack.java:3039)
│ ActivityStackSupervisor.startSpecificActivityLocked (ActivityStackSupervisor.java:1007)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ ActivityStackSupervisor.startSpecificActivityLocked
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ Thread: Binder:1819_11
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ Binder.execTransact (Binder.java:994)
│ Binder.execTransactInternal (Binder.java:1021)
│ IActivityTaskManager$Stub.onTransact (IActivityTaskManager.java:1981)
│ ActivityTaskManagerService.activityPaused (ActivityTaskManagerService.java:1714)
│ ActivityStack.activityPausedLocked (ActivityStack.java:1769)
│ ActivityStack.completePauseLocked (ActivityStack.java:1882)
│ RootActivityContainer.ensureActivitiesVisible (RootActivityContainer.java:810)
│ RootActivityContainer.ensureActivitiesVisible (RootActivityContainer.java:823)
│ ActivityDisplay.ensureActivitiesVisible (ActivityDisplay.java:1315)
│ ActivityStack.ensureActivitiesVisibleLocked (ActivityStack.java:2184)
│ ActivityStack.makeVisibleAndRestartIfNeeded (ActivityStack.java:2389)
│ ActivityStackSupervisor.startSpecificActivityLocked (ActivityStackSupervisor.java:1007)
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ ActivityStackSupervisor.startSpecificActivityLocked
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────
ActivityMetricsLogger
RootActivityContainer
Luncher
应用作为客户端通过 IPC 机制将新应用的启动信息传送到 IActivityTaskManager
服务端IActivityTaskManager
服务端代码的出处了IActivityTaskManager
是如何发挥作用的➜ generic_x86 emulator -help
Android Emulator usage: emulator [options] [-qemu args]
options:
-list-avds list available AVDs
-sysdir <dir> search for system disk images in <dir>
-system <file> read initial system image from <file>
-writable-system make system image writable after 'adb remount'
-datadir <dir> write user data into <dir>
-kernel <file> use specific emulated kernel
-ramdisk <file> ramdisk image (default <system>/ramdisk.img
-image <file> obsolete, use -system <file> instead
-initdata <file> same as '-init-data <file>'
-data <file> data image (default <datadir>/userdata-qemu.img
-partition-size <size> system/data partition size in MBs
-cache <file> cache partition image (default is temporary file)
-cache-size <size> cache partition size in MBs
-no-cache disable the cache partition
-nocache same as -no-cache
-sdcard <file> SD card image (default <datadir>/sdcard.img
-snapstorage <file> file that contains all state snapshots (default <datadir>/snapshots.img)
-no-snapstorage do not mount a snapshot storage file (this disables all snapshot functionality)
-snapshot <name> name of snapshot within storage file for auto-start and auto-save (default 'default-boot')
-no-snapshot perform a full boot and do not do not auto-save, but qemu vmload and vmsave operate on snapstorage
-no-snapshot-save do not auto-save to snapshot on exit: abandon changed state
-no-snapshot-load do not auto-start from snapshot: perform a full boot
-snapshot-list show a list of available snapshots
-no-snapshot-update-time do not do try to correct snapshot time on restore
-wipe-data reset the user data image (copy it from initdata)
-avd <name> use a specific android virtual device
-skindir <dir> search skins in <dir> (default <system>/skins)
-skin <name> select a given skin
-no-skin deprecated: create an AVD with no skin instead
-noskin same as -no-skin
-memory <size> physical RAM size in MBs
-cores <number> Set number of CPU cores to emulator
-accel <mode> Configure emulation acceleration
-no-accel Same as '-accel off'
-ranchu Use new emulator backend instead of the classic one
-engine <engine> Select engine. auto|classic|qemu2
-netspeed <speed> maximum network download/upload speeds
-netdelay <delay> network latency emulation
-netfast disable network shaping
-code-profile <name> enable code profiling
-show-kernel display kernel messages
-shell enable root shell on current terminal
-no-jni disable JNI checks in the Dalvik runtime
-nojni same as -no-jni
-logcat <tags> enable logcat output with given tags
-no-audio disable audio support
-noaudio same as -no-audio
-audio <backend> use specific audio backend
-radio <device> redirect radio modem interface to character device
-port <port> TCP port that will be used for the console
-ports <consoleport>,<adbport> TCP ports used for the console and adb bridge
-onion <image> use overlay PNG image over screen
-onion-alpha <%age> specify onion-skin translucency
-onion-rotation 0|1|2|3 specify onion-skin rotation
-dpi-device <dpi> specify device's resolution in dpi (default 165)
-scale <scale> scale emulator window (deprecated)
-http-proxy <proxy> make TCP connections through a HTTP/HTTPS proxy
-timezone <timezone> use this timezone instead of the host's default
-dns-server <servers> use this DNS server(s) in the emulated system
-cpu-delay <cpudelay> throttle CPU emulation
-no-boot-anim disable animation for faster boot
-no-window disable graphical window display
-version display emulator version number
-report-console <socket> report console port to remote socket
-gps <device> redirect NMEA GPS to character device
-shell-serial <device> specific character device for root shell
-tcpdump <file> capture network packets to file
-bootchart <timeout> enable bootcharting
-charmap <file> use specific key character map
-prop <name>=<value> set system property on boot
-shared-net-id <number> join the shared network, using IP address 10.1.2.<number>
-nand-limits <nlimits> enforce NAND/Flash read/write thresholds
-gpu <mode> set hardware OpenGLES emulation mode
-camera-back <mode> set emulation mode for a camera facing back
-camera-front <mode> set emulation mode for a camera facing front
-webcam-list lists web cameras available for emulation
-screen <mode> set emulated screen mode
-force-32bit always use 32-bit emulator
-selinux <disabled|permissive> Set SELinux to either disabled or permissive mode
-unix-pipe <path> Add <path> to the list of allowed Unix pipes
-fixed-scale Use fixed 1:1 scale for the initial emulator window.
-wait-for-debugger Pause on launch and wait for a debugger process to attach before resuming
-skip-adb-auth Skip adb authentication dialogue
-qemu args... pass arguments to qemu
-qemu -h display qemu help
-verbose same as '-debug-init'
-debug <tags> enable/disable debug messages
-debug-<tag> enable specific debug messages
-debug-no-<tag> disable specific debug messages
-help print this help
-help-<option> print option-specific help
-help-disk-images about disk images
-help-debug-tags debug tags for -debug <tags>
-help-char-devices character <device> specification
-help-environment environment variables
-help-virtual-device virtual device management
-help-sdk-images about disk images when using the SDK
-help-build-images about disk images when building Android
-help-all prints all help content
[正则匹配链接
[]()
语法上有局限性 , 如有疑虑可查看本文原文](https://github.com/TomGarden/tom-notes/blob/master/_posts/Collections/Android/AndroidStudio/下载 ndk .md)
2018-03-05 17:29:48
今天下载 ndk 出现连接超时的现象,通过代理服务器下载有感觉太慢。
于是直接手动下载下来了,下载之后有不太确定如何使用,在网络上查找也没有找到确切的操作指南。
在中期 AndroidSutido 之后连接超时的现象不修自复了
package.xml
,当然了该文件不一定会起到什么作用。因为打开查看里面是一些版权信息。总结,下次出现连接超时的状况完全可以手动下载并且解压到默认目录: ~/sdk/ndk-build
API 25
两个比较重要的属性是
有关 call_log
的拼装包括如下:
sudo apt-get install flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl valgrind
apt-cache search libwxgtk
sudo apt-get install flex bison gperf libsdl-dev libesd0-dev libwxgtk3.0-dev build-essential zip curl valgrind
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.3.1
TARGET_PRODUCT=generic
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=GRH78
============================================
Checking build tools versions...
build/core/prebuilt.mk:91: *** recipe commences before first target. Stop.
repo 命令
切换某个版本的命令:
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-10.0.0_r39
其中 android-4.0.1_r1
即为我们即将切换的编译版本 , 这实际上是一个 AOSP 分支 , 那么如何查看我们可选分支有哪些呢?
从代码实现角度尝试理解 Handler 通信细节疑惑点
当前主要探究的方向有二:
handler.post(Runnable{})
是如何实现的(没有触发 Handler.handMessage
回调)handler.sendMessage(msg)
当 msg = Message(handler,Runnable())
是如何实现的我在网络上找到了 C++ 的 Slack 讨论组 , 英文的 , 对我来说有些障碍 .
对于不是自己提问的情况下 , 难以耐着性子阅读和理解 .
我没有找到中文相关的 c++ 讨论组 , 所以我创建了一个 : Slack C++ 中文 群组 讨论 C++ 相关
阅读源代码必须要画图,如果没有图
碰到一个方法应该先知道它的目的/作用是什么
一个方法有两个层次,读者需要自行判断自己想要的是什么。
在源代码阅读的过程中,我们多数时候不是从整个系统的开始处阅读的。
这会导致一些参数的初始化过程我们不太清楚。
这一问题在有的时候我们可以根据猜测和网络上已经有的信息来规避。
但是也有些代码在查阅的时候强依赖这些参数(对象)的细节信息,这就需要我们返回去了解该参数(对象)的初始化过程。
要知道除非我们会退到整个源代码项目的入口点,否则我们始终回不可预期的遇到需要代码回溯的问题。
现在我们还是走的碰到问题然后回溯的路子。
我们期望在有一天回溯到某一个节点的时候,该节点可以很大程度上避免今后的回溯过程。也就是将其作为源码入口点。
ASO是“应用商店优化”的简称。ASO(App store Optimization)就是提升你APP在各类APP应用商店/市场排行榜和搜索结果排名的过程。类似普通网站针对搜索引擎的优化,即SEO(Search Engine Optimization)优化。ASO优化就是利用App Store的搜索规则和排名规则让APP更容易被用户搜索或看到。
操作之前的统计数据_七麦/禅大师_可查
各个Android应用市场的实施维度大体相同,各种维度的权重不同效果各有差异,总体路线
名称
关键词
下载量
评论
免费活动(首发\加官)
CPD,竞价排名
# 执行 lunch 不加参数即可
lunch
m clean
.tom_shell_profile
) : ulimit -S -n 2048
source build/envsetup.sh
lunch aosp_x86-eng
m
注意事项:
下文 adb 命令的执行状态和 emulator 的执行状态一样 , 都是先执行过了如下命令:
source build/envsetup.sh
lunch
修改过的文件的路径 frameworks/base/services/core/java/com/android/server/wm
android.util.Log
的调用# 1. 这个路径没有太明确的判断是试出来的逐层试, 并观察
# 2. 太深的路径会导致修改没有被应用,这个原因暂不深究 .
# 失败的测试路径 : cd frameworks/base/services/core/java/com/android/server/wm
# 3. 随着修改的文件的越来越多 , 这个路径要随之变化
# 4. 如果有必要使用 `mm java` 会大大提高编译速度
# 但是携带 java 命令常常导致编译失败 , 失败了删除它再试一次或需能成功
cd frameworks/base/services
mm java
编译完成将新的编译产物应用到模拟器上
# -writable-system 如果没有这个命令 adb remount 可能会失败
$ emulator -writable-system
执行同步操作动作前, 需要先获取模拟器文件系统的操作权限
adb root
adb disable-verity # https://source.android.com/security/verifiedboot/dm-verity
# 启动时验证会尽力确保所有已执行代码均来自可信来源 , 此命令为关闭此验证动作
adb reboot
adb root
adb remount
执行文件同步动作
$ adb sync // Sync the updated module to the device
$ adb shell stop // Stopping the shell
$ adb shell start // Starting the shell again
然后可以验证自己想修改是否生效了 , 我生效了
我们希望查看某一个函数相关的调用栈 , android.util.Log
需要大量的编码, 而且不是很直观
frameworks/base/core/java/android/util/tom_logger
对文件的修改情况
framework/base/service
中的某些文件调用了 Log
/ TomLogger
framework/base/core/java
中添加了 tom_logger/TomLogger
相关日志工具类文件编译情况
framework/base/service
没有编译 framework/base/core/java
异常情况
在异常一
的基础上增加对 framework/base/core/java
涉及文件的编译动作
$ cd frameworks/base/core
$ mm java # 由于我们只修改了 java 代码, 此命令应该可以降低编译成本
重新全量编译 , 得到有意义的异常帮助信息 , 并解决了问题(新添加的代码运行正常, 调用栈清晰)
$ cd aosp
$ m clean
$ m
FAILED: out/soong/.intermediates/frameworks/base/api-stubs-docs/android_common/check_current_api.timestamp
error: Added package android.util.tom_logger [AddedPackage]
Aborting: Found compatibility problems checking the public API against the API in /Volumes/beyourself/AOSP/aosp/frameworks/base/api/current.txt
-e
******************************
You have tried to change the API from what has been previously approved.
To make these errors go away, you have two choices:
1. You can add '@hide' javadoc comments to the methods, etc. listed in the
errors above.
2. You can update current.txt by executing the following command:
make api-stubs-docs-update-current-api
To submit the revised current.txt to the main Android repository,
you will need approval.
******************************
$ make api-stubs-docs-update-current-api
#### build completed successfully (01:55 (mm:ss)) ####
$ m
#### build completed successfully (14:09 (mm:ss)) ####
cat build/envsetup.sh
hmm
2.5.2 小节中出现的关于 aosp/frameworks/base/api/current.txt
的细节问题暂不深究
进度小计
当前进度 : 在 /Volumes/beyourself/AOSP/aosp/frameworks/base/core/java
执行 mm java
会在 30 min 后编译失败, 跟进这个异常 :
m help
# mm help 和下面的内容也一样
➜ aosp m help
The basic Android build process is:
cd /Volumes/beyourself/AOSP/aosp
source build/envsetup.sh # Add "lunch" (and other utilities and variables)
# to the shell environment.
lunch [<product>-<variant>] # Choose the device to target.
m -j [<goals>] # Execute the configured build.
Usage of "m" imitates usage of the program "make".
See /Volumes/beyourself/AOSP/aosp/build/make/Usage.txt for more info about build usage and concepts.
Common goals are:
clean (aka clobber) equivalent to rm -rf out/
清除编译动作所产生的所有文件
checkbuild Build every module defined in the source tree
droid Default target
nothing Do not build anything, just parse and validate the build structure
java Build all the java code in the source tree
native Build all the native code in the source tree
host Build all the host code (not to be run on a device) in the source tree
target Build all the target code (to be run on the device) in the source tree
(java|native)-(host|target)
(host|target)-(java|native)
Build the intersection of the two given arguments
# 下面几个字段的含义暂不能明晰呢
snod Quickly rebuild the system image from built packages
Stands for "System, NO Dependencies"
vnod Quickly rebuild the vendor image from built packages
Stands for "Vendor, NO Dependencies"
pnod Quickly rebuild the product image from built packages
Stands for "Product, NO Dependencies"
psnod Quickly rebuild the product_services image from built packages
Stands for "ProductServices, NO Dependencies"
onod Quickly rebuild the odm image from built packages
Stands for "ODM, NO Dependencies"
So, for example, you could run:
cd /Volumes/beyourself/AOSP/aosp
source build/envsetup.sh
lunch aosp_arm-userdebug
m -j java
to build all of the java code for the userdebug variant of the aosp_arm device.
#### build completed successfully (1 seconds) ####
Linxu 读取 mac 分区
#关闭Journal
$ diskutil disableJournal disk0s2
Journaling has been disabled on disk0s2
#打开Journal
$ diskutil enableJournal disk0s2
Journaling has been enabled on disk0s2
too many open files soong bootstrap failed with: exit status 1
在 macOS 中,可同时打开的文件描述符的默认数量上限太低,在高度并行的构建流程中,可能会超出此上限。如需提高此上限,请将下列行添加到 ~/.bash_profile 中:
//如果按照官方的建议设置了 1024 还是提示这个错误 , 可以尝试 2048
set the number of open files to be 1024
ulimit -S -n 1024
调整 Java 的对大小设置 export _JAVA_OPTIONS="-Xmx6g"
参考:https://stackoverflow.com/questions/60468693/java-outofmemoryerror-when-building-aosp-10
➜ aosp m
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=10
TARGET_PRODUCT=aosp_x86
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_ARCH=x86
TARGET_ARCH_VARIANT=x86
HOST_ARCH=x86_64
HOST_OS=darwin
HOST_OS_EXTRA=Darwin-19.5.0-x86_64-10.15.5
HOST_BUILD_TYPE=release
BUILD_ID=QQ3A.200605.002.A1
OUT_DIR=out
============================================
FAILED: out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_28.0_intermediates/treble_sepolicy_tests_28.0
/bin/bash -c "(out/host/darwin-x86/bin/treble_sepolicy_tests -l out/host/darwin-x86/lib64/libsepolwrap.dylib -f out/target/product/generic_x86/obj/ETC/plat_file_contexts_intermediates/plat_file_contexts -f out/target/product/generic_x86/obj/ETC/vendor_file_contexts_intermediates/vendor_file_contexts -b out/target/product/generic_x86/obj/ETC/built_plat_sepolicy_intermediates/built_plat_sepolicy -m out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_28.0_intermediates/28.0_mapping.combined.cil -o out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_28.0_intermediates/built_28.0_plat_sepolicy -p out/target/product/generic_x86/obj/ETC/sepolicy_intermediates/sepolicy -u out/target/product/generic_x86/obj/ETC/built_plat_sepolicy_intermediates/base_plat_pub_policy.cil --fake-treble ) && (touch out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_28.0_intermediates/treble_sepolicy_tests_28.0 )"
/bin/bash: line 1: 21672 Segmentation fault: 11 ( out/host/darwin-x86/bin/treble_sepolicy_tests -l out/host/darwin-x86/lib64/libsepolwrap.dylib -f out/target/product/generic_x86/obj/ETC/plat_file_contexts_intermediates/plat_file_contexts -f out/target/product/generic_x86/obj/ETC/vendor_file_contexts_intermediates/vendor_file_contexts -b out/target/product/generic_x86/obj/ETC/built_plat_sepolicy_intermediates/built_plat_sepolicy -m out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_28.0_intermediates/28.0_mapping.combined.cil -o out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_28.0_intermediates/built_28.0_plat_sepolicy -p out/target/product/generic_x86/obj/ETC/sepolicy_intermediates/sepolicy -u out/target/product/generic_x86/obj/ETC/built_plat_sepolicy_intermediates/base_plat_pub_policy.cil --fake-treble )
[ 78% 63452/80802] build out/target/product/generic_x86/obj/ETC/sepolicy_tests_intermediates/sepolicy_tests
FAILED: out/target/product/generic_x86/obj/ETC/sepolicy_tests_intermediates/sepolicy_tests
/bin/bash -c "(out/host/darwin-x86/bin/sepolicy_tests -l out/host/darwin-x86/lib64/libsepolwrap.dylib -f out/target/product/generic_x86/obj/ETC/plat_file_contexts_intermediates/plat_file_contexts -f out/target/product/generic_x86/obj/ETC/vendor_file_contexts_intermediates/vendor_file_contexts -p out/target/product/generic_x86/obj/ETC/sepolicy_intermediates/sepolicy ) && (touch out/target/product/generic_x86/obj/ETC/sepolicy_tests_intermediates/sepolicy_tests )"
/bin/bash: line 1: 21667 Segmentation fault: 11 ( out/host/darwin-x86/bin/sepolicy_tests -l out/host/darwin-x86/lib64/libsepolwrap.dylib -f out/target/product/generic_x86/obj/ETC/plat_file_contexts_intermediates/plat_file_contexts -f out/target/product/generic_x86/obj/ETC/vendor_file_contexts_intermediates/vendor_file_contexts -p out/target/product/generic_x86/obj/ETC/sepolicy_intermediates/sepolicy )
[ 78% 63453/80802] build out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_26.0_intermediates/treble_sepolicy_tests_26.0
FAILED: out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_26.0_intermediates/treble_sepolicy_tests_26.0
/bin/bash -c "(out/host/darwin-x86/bin/treble_sepolicy_tests -l out/host/darwin-x86/lib64/libsepolwrap.dylib -f out/target/product/generic_x86/obj/ETC/plat_file_contexts_intermediates/plat_file_contexts -f out/target/product/generic_x86/obj/ETC/vendor_file_contexts_intermediates/vendor_file_contexts -b out/target/product/generic_x86/obj/ETC/built_plat_sepolicy_intermediates/built_plat_sepolicy -m out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_26.0_intermediates/26.0_mapping.combined.cil -o out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_26.0_intermediates/built_26.0_plat_sepolicy -p out/target/product/generic_x86/obj/ETC/sepolicy_intermediates/sepolicy -u out/target/product/generic_x86/obj/ETC/built_plat_sepolicy_intermediates/base_plat_pub_policy.cil --fake-treble ) && (touch out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_26.0_intermediates/treble_sepolicy_tests_26.0 )"
/bin/bash: line 1: 21668 Segmentation fault: 11 ( out/host/darwin-x86/bin/treble_sepolicy_tests -l out/host/darwin-x86/lib64/libsepolwrap.dylib -f out/target/product/generic_x86/obj/ETC/plat_file_contexts_intermediates/plat_file_contexts -f out/target/product/generic_x86/obj/ETC/vendor_file_contexts_intermediates/vendor_file_contexts -b out/target/product/generic_x86/obj/ETC/built_plat_sepolicy_intermediates/built_plat_sepolicy -m out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_26.0_intermediates/26.0_mapping.combined.cil -o out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_26.0_intermediates/built_26.0_plat_sepolicy -p out/target/product/generic_x86/obj/ETC/sepolicy_intermediates/sepolicy -u out/target/product/generic_x86/obj/ETC/built_plat_sepolicy_intermediates/base_plat_pub_policy.cil --fake-treble )
[ 78% 63454/80802] build out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_27.0_intermediates/treble_sepolicy_tests_27.0
FAILED: out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_27.0_intermediates/treble_sepolicy_tests_27.0
/bin/bash -c "(out/host/darwin-x86/bin/treble_sepolicy_tests -l out/host/darwin-x86/lib64/libsepolwrap.dylib -f out/target/product/generic_x86/obj/ETC/plat_file_contexts_intermediates/plat_file_contexts -f out/target/product/generic_x86/obj/ETC/vendor_file_contexts_intermediates/vendor_file_contexts -b out/target/product/generic_x86/obj/ETC/built_plat_sepolicy_intermediates/built_plat_sepolicy -m out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_27.0_intermediates/27.0_mapping.combined.cil -o out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_27.0_intermediates/built_27.0_plat_sepolicy -p out/target/product/generic_x86/obj/ETC/sepolicy_intermediates/sepolicy -u out/target/product/generic_x86/obj/ETC/built_plat_sepolicy_intermediates/base_plat_pub_policy.cil --fake-treble ) && (touch out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_27.0_intermediates/treble_sepolicy_tests_27.0 )"
/bin/bash: line 1: 21670 Segmentation fault: 11 ( out/host/darwin-x86/bin/treble_sepolicy_tests -l out/host/darwin-x86/lib64/libsepolwrap.dylib -f out/target/product/generic_x86/obj/ETC/plat_file_contexts_intermediates/plat_file_contexts -f out/target/product/generic_x86/obj/ETC/vendor_file_contexts_intermediates/vendor_file_contexts -b out/target/product/generic_x86/obj/ETC/built_plat_sepolicy_intermediates/built_plat_sepolicy -m out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_27.0_intermediates/27.0_mapping.combined.cil -o out/target/product/generic_x86/obj/ETC/treble_sepolicy_tests_27.0_intermediates/built_27.0_plat_sepolicy -p out/target/product/generic_x86/obj/ETC/sepolicy_intermediates/sepolicy -u out/target/product/generic_x86/obj/ETC/built_plat_sepolicy_intermediates/base_plat_pub_policy.cil --fake-treble )
21:05:28 ninja failed with: exit status 1
#### failed to build some targets (02:10:52 (hh:mm:ss)) ####
问题的答案
Fix sepolicy_tests on Mac 10.15
即可找到这个答案11.1
字段即可 , 但是还有其他未能逾越的异常adb sync
执行失败# 执行失败
➜ aosp adb sync
/Volumes/beyourself/AOSP/aosp/out/target/product/generic_x86/data/: 5 files pushed. 37.9 MB/s (1141778 bytes in 0.029s)
adb: error: failed to copy '/Volumes/beyourself/AOSP/aosp/out/target/product/generic_x86/system/framework/ipmemorystore-aidl-interfaces-V1-java.jar' to '/system/framework/ipmemorystore-aidl-interfaces-V1-java.jar': remote couldn't create file: Read-only file system
# 观察状况
➜ aosp adb root
adbd is already running as root
➜ aosp adb shell
generic_x86:/ # cd system/
eneric_x86:/system # ls -l
drwxr-xr-x 2 root root 4096 2020-09-14 02:09 framework
generic_x86:/system # whoami
root
# 说明即使是 root 用户也没有 framework 文件夹的写权限 , 虽然看起来是有的
# 关闭安全验证
adb disable-verity
# 重新启动
adb reboot
adb root
# 重新挂载文件系统失败
adb remount
emulator -writable-system
启动模拟器即可完成重新挂载点动作https://stackoverflow.com/q/72180366/7707781
直接命令行通过 spawn-fcgi 启动的程序 , 如果发生 crash 如何收集 core 文件 ?
探索 C++ Web 编程
spawn-fcgi
.FCGI Wrap
使用的也是 spawn-fcgi , 这是题外话 .crash_demo
故意 throw "测试异常, 观察 core 文件"
, 编译生成 crash_demo.run
sudo nginx -c my_nginx_custom.config
ulimit -c unlimited
spawn-fcgi -a 127.0.0.1 -p 9000 -f /path/crash_demo.run
crash_demo.run
所在目录没有看到 core
文件猜测(2
是我倾向的答案)
core
文件没有生成core
文件生成了 , 但是我不知道文件位置 ;有人知道问题所在吗 ?
I run "crash_demo.run"
by spawn-fcgi
.
How to collect core
file .
I'm exolore C++ Web Programming .
FCGI Wrap
be drive by spawn-fcgi , Of course this is off topic .crash_demo
) .crash_demo
insert code throw "test exception str, check _core_ file"
, build got crash_demo.run
sudo nginx -c my_nginx_custom.config
ulimit -c unlimited
crash_demo.run
by spawn-fcgi
: spawn-fcgi -a 127.0.0.1 -p 9000 -f /path/crash_demo.run
crash_demo
http request , got 5xx
response .
crash_demo.run
is located does not see the core
fileMy guess
core
file not generate .core
file is generated , but i don't the file path .Does anyone know what happened?
My question is flawed .
Thanks @sehe , my step :
/proc/sys/kernel/core_pattern
core
-> core_%e_%p_%t
ulimit -c unlimited
spawn-fcgi -a 127.0.0.1 -p 9000 -f /path/crash_demo.run
sudo find / core_ | grep core_crash_demo
/path/core_crash_demo._5080_1652169152
So , my guess on my question is failed .
The fact is , I don't generate core
file , when my question.
When my generated core
file successed , the core
file path is crash_demo.run
parent directory .
再次遇到此问题 , 我们想做两件事
core dump 文件生成的细节
主要参考内容 : core manual
core manual 中设计的点很多 , 不同的情况可能遇到不同的问题, 不过基本可以确认,阅读此文件可以解决大多数问题。
这里我只写出自己关注的点。
要生成 core dump 有几个前提条件 :
ulimit -a
查看 ; ulimit -c unlimited
修改/proc/sys/kernel/core_pattern
,
core
, 除非被修改过|
意味通过管道后进一步执行后续命令 , 细节需要再细读文档,不再展开。core_%e_%p_%t
-> core_可执行文件名_pid_时间戳
sudo bash -c 'echo core_%e_%p_%t > /proc/sys/kernel/core_pattern'
/tmp/core_%e_%p_%t
, core dump 会放到 /tmp
目录下再次执行异常程序后可以使用 find 命令查找 core 文件位置了
sudo find / core_ | grep core_
~/a/b/c/d/exe.run
~$ /a/b/c/d/exe.run
~/core
core dump 文件如何使用
launch.json
增加 属性 coreDumpPath
: https://code.visualstudio.com/docs/cpp/cpp-debug#_memory-dump-debuggingwe whant to know two point :
Reference the file : core manual
core manual write many point , I just list the point i care :
ulimit -a
check limit / ulimit -c unlimited
cancel limit/proc/sys/kernel/core_pattern
core
core_%e_%p_%t
mean core_your_execute_file_name_pid_timestemp
sudo bash -c 'echo core_%e_%p_%t > /proc/sys/kernel/core_pattern'
now run your exception , you can got core file .
sudo find / core_ | grep core_
launch.json
, add coreDumpPath
, refrence : https://code.visualstudio.com/docs/cpp/cpp-debug#_memory-dump-debuggingNgins server , HTTP post request with header -H 'Content-Length
, not response .
But , if not Content-Length
header, the result is normal .
I'm exolore C++ Web Programming .
without header Content-Length
curl -X POST 'http://104.225.154.215:8080/fcgi_test/' \
-H 'Content-Length: 135' \
-v \
'{
"synthetics_condition": {
"name": "Check Failure",
"monitor_id": "XXX",
"runbook_url": "XXX",
"enabled": true
}
}'
* Trying 104.225.154.215...
* TCP_NODELAY set
* Connected to 104.225.154.215 (104.225.154.215) port 8080 (#0)
> POST /fcgi_test/ HTTP/1.1
> Host: 104.225.154.215:8080
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Length: 135
>
* Empty reply from server
* Connection #0 to host 104.225.154.215 left intact
curl: (52) Empty reply from server
curl: (3) nested brace in URL position 29:
{
"synthetics_condition": {
"name": "Check Failure",
"monitor_id": "XXX",
"runbook_url": "XXX",
"enabled": true
}
}
^
* Closing connection 0
Connect to 127.0.0.1:8888 [/127.0.0.1] failed: Connection refused (Connection refused)
Connect to 127.0.0.1:1083 [/127.0.0.1] failed: Connection refused (Connection refused)
invalidate and restart
gradle.properties
文件中是否有多余的代理代码
~/.gradle/gradle.properties
project_path/gradle.properties
AndroidStudio 查看 Plugin Marketplace 不展示内容
application install failed
the device might have stale dexed jars that don't match the current version
原因 : 设备内存不足了
解决 : 清理下或者加内存
好我们就开始娱乐了。
分享到 tom-notes 的关联目录中
kotlin 克隆对象的方法
class TetrisSquareDelegate : SquareDelegate(), Cloneable {
var calculateWidth: Int = 0 /*控件水平尺寸(宽度) , 在 OnMeasuer 计算得出*/
var calculateHeight: Int = 0 /*控件垂直尺寸(高度) , 在 OnMeasuer 计算得出*/
public override fun clone(): TetrisSquareDelegate {
return super.clone() as TetrisSquareDelegate
}
}
Gson 序列化/反序列化
Unable to invoke no-args constructor for interface kotlin.Lazy. Registering an InstanceCreator with Gson for this type may fix this problem.
/** 快速复制对象 , 不只是复制索引
* 也可以通过对象继承 kotlin.Cloneable 实现这一能力
* */
inline fun <reified T> Any.cloneObj(): T {
return this.toJsonString().toObjFromJsonString<T>()
}
inline fun Any.toJsonString(): String = Gson().toJson(this)
inline fun <reified T> String.toObjFromJsonString(): T = Gson().fromJson(this, T::class.java)
反序列化子类问题可以参考
\frameworks\native\cmds\servicemanager\service_manager.c
\frameworks\base\cmds\app_process\app_main.cpp
概述:使用更少的硬件资源达到更优的功能实现,这个取舍做的越好意味着性能越高。
以下三点来自于 Android Profiler 工具当前的功能实现。
Ubuntu 16.04
/media/tom/os/bin/repo
/media/tom/os/AOSP/android-****/.repo
.repo
文件夹整个剪切过去$ repo init
fatal: Cannot get https://gerrit.googlesource.com/git-repo/clone.bundle
fatal: error [Errno 101] Network is unreachable
直接翻墙解决 > 恰好我有 VPS 和 Shadowsocks = 失败
解决方案:
git clone https://gerrit-googlesource.lug.ustc.edu.cn/git-repo
repo init
为了应对重复失败:error: Exited sync due to fetch errors
。
我们找到一个脚本:
#!/bin/sh
repo sync -j4
while [ $? -ne 0 ]
do
repo sync -j4
done
听说 Android 源码一共就 4~8G 但是我们都下载了 60+G 还没有完这然我怀疑下错了,所以我想再来一次。
在 repo sync -c
出现错误 (UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 9: ordinal not in range(128))
我们认为是python 默认编码的原因于是修改 python 默认编码为 utf8 (从默认的 ascii 修改成 utf8)
http://shirley-ren.iteye.com/blog/1018750
以管理员身份运行
有些类文件我们 google 很轻松就找到了源码,但是这和我们下载下来的源码的分类和路径不大相同:这时什么原因我们应该如何根据 google 到的代码在本地找到对应?
例如我们当前在 google 找到了目标代码
android / platform / libcore / android-4.3_r3 / . / luni / src / main / java / libcore / io / Libcore.java
`I:\AOSP\android-4.4.4_r1\libcore\ luni \ src \ main \ java \ libcore \ io`
Syncing work tree: 97% (437/450)error: The following untracked working tree files would be overwritten by checkout:
10/android.jar
10/framework.aidl
……//代表一堆文件
Android.mk
CleanSpec.mk
api/1.xml
……//代表一堆文件
current/Android.mk
……//代表一堆文件
Please move or remove them before you can switch branches.
Aborting
Syncing work tree: 100% (450/450), done.
error: prebuilts/sdk/: platform/prebuilts/sdk checkout 48df57e9d07887b7621d51cc93ae7600815a842d
解决方案:将上述文件删除重新执行 sync 命令即可
info: A new version of repo is available
warning: project 'repo' branch 'master' is not signed
warning: Skipped upgrade to unverified version
尚未解决
https://support.google.com/pixelphone/answer/4457705?hl=zh-Hans
在清华镜像站, 下载压缩包 ,解压之后直接执行 repo sync
即可检出所有 AOSP 代码 .
这里需要搞清楚的是,
查看所有分支
cd .repo/manifests
git branch -a
# 或
git branch -a | cut -d / -f 3
切换分支
$ repo init -b android-4.2.2_r1
repo切换分支后,cat .repo/manifests.git/config 可见以下内容,在branch "default"的merge那里,没切换前是merge = refs/heads/master,切换后如下:
[core]
repositoryformatversion = 0
filemode = false
[filter "lfs"]
smudge = git-lfs smudge --skip -- %f
[remote "origin"]
url = git://mirrors.ustc.edu.cn/aosp/platform/manifest
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "default"]
remote = origin
merge = refs/heads/android-4.2.2_r1
# 创建自己的新分支
$ repo start gingerbread-release --all
# 查看当前的分支
$ repo branches
2021-01-11 10:21:08 : 今天应该编译 AOSP 使其可运行 emulate
source build/envsetup.sh
lunch # 好像是 23
emulator
public class ConnectivityManager
extends Object
java.lang.Object
↳ android.net.ConnectivityManager
Class that answers queries about the state of network connectivity. It also notifies applications when network connectivity changes.
The primary responsibilities of this class are to:
Instances of this class must be obtained using Context.getSystemService(Class) with the argument ConnectivityManager.class or Context.getSystemService(String) with the argument Context.CONNECTIVITY_SERVICE.
涉及的知识点为 GNU-C 扩展
/* Evaluate EXPRESSION, and repeat as long as it returns -1 with `errno'
set to EINTR. */
# define TEMP_FAILURE_RETRY(expression) \
(__extension__ \
({ long int __result; \
do __result = (long int) (expression); \
while (__result == -1L && errno == EINTR); \
__result; }))
作用:当表达式的值为为 -1 并且 errno 为 EINTR 的时候进入死循环,直到不满足循环条件。
extension 关键字
复合语句
=================================================================================================
1-dexdump
tom@DESKTOP-P2EBEQB MINGW64 /e/dev_kit/android_sdk/build-tools/27.0.3
$ ./dexdump.exe
dexdump: no file specified
Copyright (C) 2007 The Android Open Source Project
dexdump: [-c] [-d] [-f] [-h] [-i] [-l layout] [-m] [-t tempfile] dexfile...
-c : verify checksum and exit
-d : disassemble code sections ----
-f : display summary information from file header
-h : display file header details
-i : ignore checksum failures
-l : output layout, either 'plain' or 'xml'
-m : dump register maps (and nothing else)
-t : temp file name (defaults to /sdcard/dex-temp-*)
AOSP路径: I:\AOSP\android-4.4.4_r1\dalvik\vm\DvmDex.h
Configuration 'compile' is obsolete and has been replaced with 'implementation' and 'api'.
It will be removed at the end of 2018. For more information see: http://d.android.com/r/tools/update-dependency-configurations.html
Unable to create Debug Bridge: Unable to start adb server: adb server version (39) doesn't match this client (40); killing...
ADB server didn't ACK
Full server startup log: /tmp/adb.1000.log
Server had pid: 4763
--- adb starting (pid 4763) ---
adb I 08-21 15:47:02 4763 4763 main.cpp:56] Android Debug Bridge version 1.0.40
adb I 08-21 15:47:02 4763 4763 main.cpp:56] Version 4797878
adb I 08-21 15:47:02 4763 4763 main.cpp:56] Installed as /beyourself/DevTool/DevKit/Sdk/platform-tools/adb
'/beyourself/DevTool/DevKit/Sdk/platform-tools/adb start-server' failed -- run manually if necessary
solution : File > Sync Project with Gradle Files
无差别抄录:http://blog.csdn.net/yiyiyf/article/details/52693800
进入Android Studio的安装目录,进入bin文件夹,用文本编辑软件打开idea.properties,去掉以下两项的注释符号#,修改对应的路径为新路径即可。
#---------------------------------------------------------------------
# Uncomment this option if you want to customize path to IDE config folder. Make sure you're using forward slashes.
#---------------------------------------------------------------------
# idea.config.path=${user.home}/.AndroidStudio/config
idea.config.path=D:/.AndroidStudio/config
#---------------------------------------------------------------------
# Uncomment this option if you want to customize path to IDE system folder. Make sure you're using forward slashes.
#---------------------------------------------------------------------
# idea.system.path=${user.home}/.AndroidStudio/system
idea.system.path=D:/.AndroidStudio/system
Gradle的配置文件夹
在Android Studio的配置选项中修改
Setting>>Build,Execution,Deployment>>Gradle>>Service directory path
这个文件夹是由Android SDK配置模拟器生成的,也是最占空间的一个。
首先,需要添加一个系统的环境变量ANDROID_SDK_HOME ,
变量名其实有些误导人,这个如果Google官方定义成AVD_HOME可能还好一些,其实应该是模拟器的默认路径。添加好环境变量后到新的路径下修改下相应的.ini文件内的路径信息,然后重启系统生效。
一个个人博客程序 : 通过 github actions 将 github repository 中的 markdown 文件发布到该 repository 的 issues 中 .
DexClassLoader(String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent)
* public BaseDexClassLoader(String dexPath, File optimizedDirectory, String libraryPath, ClassLoader parent)
* public DexPathList(ClassLoader definingContext, String dexPath, String libraryPath, File optimizedDirectory)
* private static ArrayList splitDexPath(String path)
- private static ArrayList splitPaths(String path1, String path2, boolean wantDirectories)
- private static void splitAndAdd(String searchPath, boolean directoriesOnly, ArrayList resultList)
我们尝试了文本
又尝试了 UML 时序图
[正则匹配链接
[]()
语法上有局限性 , 如有疑虑可查看本文原文](https://github.com/TomGarden/tom-notes/blob/master/_posts/Collections/Android/Android_API_DOC/2018-08-09- android.util.Log.md)
目录
java.lang.Object
↳ android.util.Log
API 用于打印日志。
通常一应该是用 Log.v(),log.d(),log.w(),log.e 和 log.e()
方法写日志。然后你可以在 Logcat 查看日志。
日志的优先级顺序为:
除非在开发期间Verbose(详细信息)永远不应该编译到应用中。Debug日志在运行的应用中应该被除去。ERROR/WARNING应该永远保留在应用中。
提示:在应用中声明 TAG 是一个不错的实践,声明之后用该 TAG 作为参数调用日志方法。
//声明
private static final String TAG = "MyActivity";
//调用
Log.v(TAG, "index=" + i);
当你构建的字符串传递到 Log.d,编译器使用一个 StringBuilder 至少发生三次分配:StringBuilder 本身,缓冲区,String 对象。实际上还有另一次缓冲分配和复制,对于 GC 的压力更大。就是说,如果你的日志消息被过滤掉,将Android系统将做大量工作并产生大量开销。
对 Profiler/trace 有了一定了解 , 它们的标注范围主要集中在视图结构方面的耗时内容
如果想针对线程进行耗时动作划分暂时还不够全面 , 比如主线程中加载布局 和 执行 I/O 操作同时存在的情况下无法分析 I/O 相关操作的细节信息
Debug.startMethodTracing("tomyangming.trace")
//需要仔细分析的代码内容
Debug.stopMethodTracing()
Google 检索 关键字 卡顿 : developer.android.com
可以了解下 : apply from: 'http://test.com/path/other.gradle'
这样较为统一的配置就不必通过拷贝复用了
使用 GitHub Packages 发布 Android lib
之前我们使用 JCenter 作为远程仓库主要存在两个问题
所以我尝试探索其他的远程仓库
再次研究这部分内容可以考虑下 : https://jitpack.io/
GitHub Packages , 经过测试 , 上传比较快 , 同等环境下(翻墙代理) ,
从 JCenter 下载依赖 , 失败多次 ,
从 GitHub Packages 下载没有失败过
配置过程不复杂
存在的问题就是 , 使用上传到 GitHub Packages 的 Lib 还需要 提供自己的 GitHub 身份认证 ,
虽然这也不是什么复杂的操作 , 但是比起直接一行代码完成依赖 , 还是会多那么几行烦人的代码 .
碰到的问题 : aar 上传后无法查看源码 , 已经解决了 , 这个小细节等下一阶段输出文档的时候再详细描述
恩 上传到 MavenCenter 更烦人 , 所以我回来啦
配置文件 , 可以直接拷贝也可以参照上文官方指导 , 阅读后再使用
write:packages
read:packages
ext {
moduleVersionCode = 2
moduleVersionName = '0.1.6'
moduleName = 'LibLog'
mavenGroupId = 'io.github.tomgarden'
}
//这个节点和官方文档不同
task androidSourcesJar(type: Jar) {
/*生成 sources.jar 应对生成的 aar 跳转代码无法阅读的问题*/
archiveClassifier.set('sources')
from android.sourceSets.main.java.srcDirs
}
publishing {
//这个节点和官方文档不同
publications {
gpr(MavenPublication) {
groupId mavenGroupId
artifactId moduleName
version moduleVersionName
artifact("$buildDir/outputs/aar/$moduleName-release.aar")
// 将 generateSourcesJar Task 生成的 sources.jar 也一并上传
artifact(androidSourcesJar)
}
}
repositories {
maven {
name = moduleName
//仓库地址
url = uri("https://maven.pkg.github.com/TomGarden/lib_log")
credentials {
username = project.findProperty("gpr.user") ?: System.getenv("TOMGARADEN_USERNAME")
password = project.findProperty("gpr.key") ?: System.getenv("PUBLISH_LIB_TO_GITHUB_PACKAGES_TOKEN")
}
}
}
}
#
# /Volumes/tom_disk/Users/tom/.tom_shell_profile
#
################################################################
# 以前我们用 bash 作为命令语言解释器 , 这时候如果我们需要配置环境变量
# 修改啊 ~/.bash_profile 即可
#
# 后来我们使用 zsh 作为命令语言解释器 , 这时候如果我们要配置环境变量就需要
# 设置文件 ~/.zshrc
#
# 干脆我们自己写一个文件 , 然后到上述两个文件中各添加一条指令:
# source ~/.tom_shell_profile
################################################################
# 发布 Android lib 到 github 需要的 github 做身份认证的 token
# 在 Android project 中通过 `System.getenv("ANDROID_SDK_HOME")` 获取此值
# 专一用于管理 GitHub Packages [write:packages/read:packages]
export TOMGARADEN_USERNAME=TomGarden
export TOMGARADEN_WRITE_PACKAGES_TOKEN=略
export TOMGARADEN_READ_PACKAGES_TOKEN=略
#
# /Volumes/tom_disk/Users/tom/.zshrc
# /Volumes/tom_disk/Users/tom/.bash_profile
#
# 自定义环境变量设置(也可以将原文内容复制过来, 这么做是为了不同的命令解释器可复用)
source ~/.tom_shell_profile
$gradlew clean
$gradlew build
# 替换 ModuleName
$gradlew :<ModuleName>:publish
至此依赖包已经上传到 GitHub Packages 了
在要使用远程库的 Module 中添加代码
//此节点位于 ModuleName/build.gradle
dependencies {
//implementation project(path: ':LibLog')
implementation 'io.github.tomgarden:LibLog:0.1.6'
}
//此节点位于 ModuleName/build.gradle , 或者 ProjectName/build.gradle
repositories {
maven {
url = uri("https://maven.pkg.github.com/TomGarden/lib_log")
url = uri("https://maven.pkg.github.com/TomGarden/lib_pickcolor")
credentials {
//不限的 github 账户名
username = System.getenv("TOMGARADEN_USERNAME")
//与 github 账户名成对的 具有 read:packages 权限的 token
password = System.getenv("TOMGARADEN_READ_PACKAGES_TOKEN")
}
}
}
编译运行即可使用了
> Task :LibPickColor:publishGprPublicationToLibPickColorRepository FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':LibPickColor:publishGprPublicationToLibPickColorRepository'.
> Failed to publish publication 'gpr' to repository 'LibPickColor'
> Could not PUT 'https://maven.pkg.github.com/TomGarden/lib_pickcolor/io/github/tomgarden/LibPickColor/0.1.3/LibPickColor-0.1.3.aar'. Received status code 422 from server: Unprocessable Entity
如果修改名称后找不到文件 Could not read 'path/lib_pick_color-release.aar' as it does not exist.
可以参照链接 : 🔗 archivesBaseName = moduleName
github package
重复上传冲突异常# 出现这种情况是因为上传包完成后 , 项目首页没有及时刷新包信息 UI 认为上传失败重新发起上传报的异常
# 上传完成后可以稍等 2 分钟再刷新页面
> Task :lib_system_bar:publishGprPublicationToLib_system_barRepository FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':lib_system_bar:publishGprPublicationToLib_system_barRepository'.
> Failed to publish publication 'gpr' to repository 'lib_system_bar'
> Could not PUT 'https://maven.pkg.github.com/TomGarden/lib_system_bar/io/github/tomgarden/lib_system_bar/0.0.1/lib_system_bar-0.0.1.aar'. Received status code 409 from server: Conflict
我们按照 https://juejin.im/post/5c3bddeff265da616501c56b 的操作指导(没有上传公钥) ,
完成了操作 , 并且上传成功了 , 但是在 maven center 搜索不到自己上传的 lib 文件
还需要跟进
看看等等怎么样 :
不想等了 , 本次就采用 GitHub Packages
init 进程 > Zygote > System
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
init 进程通过阅读 .rc 脚本文件的方式完成动作
system/core/init.rc
这个脚本文件。
AOSP/system/core/init/readme.txt
文件中的 android init language 说明能大致了解脚本文件的意义。在 init 进程中 fork 了一个新进程,即为 zygote 进程。
/system/bin/app_process
在 zygote 程中创建了 /dev/socket/zygote 文件,将这个文件路劲和 ANDROID_SOCKET_zyogte 作为 key:value (路径为 value) 加入环境变量中。
下载 AOSP 编译完成后直接执行 emulator 即可运行刚刚编译好的镜像
在 aost/out 目录中可以找到启动模拟器所需要的景象文件 , 要启动这个模拟器 , 在编译完成后直接执行
emulator
即可
但是当设备重启后再想运行这个模拟器 :
0. cd aosp_path
source build/envsetup.sh
lunch 当时编译的那个版本号其他的没有测试
aosp_x86-eng
第 23 个选项emulator
which emulator
来查看可执行文件位置另外的说明, 我的移动硬盘有完整的代码和编译产物 , 内存不足的 PC 包含
m clean
)aosp/out/target
拷贝到 PC如果这种使用方式无法满足后续的需求再想办法清理 PC 硬盘或者换设备
修改屏幕尺寸 , 参照 ~/.android/avd
文件中的配置文件 confit.ini 进行修改和验证即可
关于购买硬件运行编译版本镜像问题:
关键词: BL / CID / V版 / 美版 / 港版
对应的流程图在 方法小计/调用栈/
DexClassLoader
app_run
The modification is mainly in "art/runtime/class_linker.cc" (ART) and "dalvik/vm/native/dalvik_system_DexFile.cpp" (DVM).
《Android 源代码情景分析》第十二章:
Activity 管理服务器 ActivityManagerService 再启动一个应用程序组件时(假设启动的就是我们想要启动的应用的 MAIN Activity),如果发现所需要的的应用程序进程还没有启动起来,他就会请求 Zygote 进程将这个应用程序进程启动起来。
Zyegote 进程通过复制自身的方式来创建一个新的应用程序进程。
应用程序启动过程中,除了可以获得一个虚拟机实例外,还可以获得一个 Binder 线程池和一个消息循环,这样,运行在它里面的应用程序组件就可以方便的使用 Android 系统的消息处理机制,以及 Binder 进程间通信机制来实现自己的业务逻辑。
在上述过程中我们关心的内容是: 创建新进程的过程中,DEX 是如何被操作的,系统正常操作 DEX 的过程和 DexHunter 操作 DEX 过程的异同。
《Android 源代码情景分析》第七章:
根 Activity 以快捷图标的形式显示在应用程序启动器中,它的启动过程就代表了一个 Android 应用程序的启动过程。子 Activity 由根 Activity 或其他子 Activiyt 启动。它们有可能与启动它们的 Activiyt 运行在同一个进程中,也有可能运行在不的进程中,这取决于它们的启动参数的配置。
我们从 Launcher.startActivitySafely 开始这一流程:当我们在 应用程序启动器 Launcher 的界面上点击一个应用程序的快捷图标时,Launcher 组件的成员函数 startActivitySafely 就会被调用来启动这个应用程序的根 Activity,其中要启动的根 Activity 信息包含在 intent 中。
过于钟情这个选项
Pixel 3A Google 系统支持到 2022 年 5 月
OPPO 2000 - A92s 6G+128G 九十度黑
3000 - Google Pixel 4a
OPPO 3000 - Reno4 5G 晶钻红 8G+128G
OPPO 2500 - Reno4 SE 超闪黑/8G+128G
0x01
> 0x02
> 0x03
在探索某一部分的细节逻辑的时候总是会需要查看源码的细节实现 , 查看当然好 , 但是能断点调试就更加棒了.
调试 Aosp 的方式有多种 , 这里我们只记录整个 AOSP 下载并调试的一点细节
File -> Project Structure -> Project : 将 Android SDK 设置为和源码版本一致
Run -> Attach Debugger to Android Process -> show all process : system_process
启动一个和 AOSP 版本相同的 模拟器 (我想编译出来的那个 img 应该是最恰当的吧 ,
但是我自己用的 AndroidStudio 之前下载的大版本相同的 , 图个方便 , 后续不满足需求再重编)
*. 测试: 在 ActivityStarter.java
类文件中 startActivityMayWait
函数多打几个断点 ,
随便一个启动 新 Activity 的动作都会击中断点
java.lang.Object
↳ android.os.Build
从系统属性中提取关于本次构建的信息。
java.lang.Object
↳ android.os.Build.VERSION
版本字符串变量
字段 | 描述 |
---|---|
BASE_OS |
本文内容可以通过通篇阅读官方文档完全获取 , 本文是按照个人思路做的流程化的笔记📒 .
所涉及的连接如下:
界面呈现是指从应用生成帧并将其显示在屏幕上的动作。要确保用户能够流畅地与您的应用互动,您的应用呈现每帧的时间不应超过 16ms,以达到每秒 60 帧的呈现速度。如果您的应用存在界面呈现缓慢的问题,系统会不得不跳过一些帧,这会导致用户感觉您的应用不流畅。我们将这种情况称为卡顿。
小节摘要 : Systrace 工具通过跟踪系统的各项资源指标输出一个跟踪文件(我们称为trace文件
) , 然后通过相应的图形界面解析工具(Perfetto/trace_viewer)将跟踪文件转换为可视可分析的报表(推荐 -3-)
trace文件
转换为可视化报表的工具 : https://ui.perfetto.dev/
旧用户界面
了 , 可以通过 Perfetto 工具的 Legacy UI
来生成旧用户界面
trace文件
, 选择进程的时候我选择了 默认的那个 re-initialized>
可用 : 这个跟 Perfetto
相比 :
Perfetto
相比选中目标线程后才可以使用检索能力 ; 检索内容可以是 Trace.beginSection
函数打的标签也可以是其他内容Slices(色块/切片)
的时候 , 是可以列举出子Slices(色块/切片)
所对应的层级关系的(可折叠)生成trace文件
的方式有二
当我们知道某个函数或者某个类有卡顿状况的时候通过以下操作可以缩小限定范围
trace文件
生成后就要将其以可视化的方式展示出来
➕
Start new profiling session -> load from file
trace文件
设置扩展名未 .trace
时间轴上的条状色块是各个 label 对应的执行时间 , 但是如果没有打自定义 label 的话 , 那些 label 都是系统默认打的;
如果是假设某一部分有卡顿想要通过这个工具验证这个假设是否成立 , 我们可以打自定义标签:
Trace.beginSection("HelloWorld")
//other code
Trace.endSection()
确保生成 trace文件
的过程中打标签的代码被执行 , 当 Perfetto 将 trace文件
可视化后就可以通过搜索标签 HelloWorld
来定位自己标签对应的Slices(色块/切片) , 通过观察这个Slices(色块/切片)的长度是否大于 16ms 即可判断是否卡顿
Android Studio Profile
: 需要先锁定目标线程 , 一般就是 Main 线程再发起搜索Perfetto
: 注意这里提到的检索不是浏览器的检索功能 , 是这个网页内部的检索功能再继续沿着Slices(色块/切片)深入其子Slices(色块/切片)即可确定到是那些类的加载或者执行导致的时间大幅消耗 , 从而做出优化
通过 卡顿帧 结合时间线继续向下缩小卡顿排查范围 如果有必要 可以结合代码进一步定位:
Trace.beginSection("HelloWorld")
//other code
Trace.endSection()
不知道某个页面某个功能是否存在卡顿的问题(肉眼感知不明显) , 通过 systrace 跟踪得到日志 , 再通过 Perfetto 分析跟踪记录 , 如何判断哪里有卡顿呢 ?
很多情况下Slices(色块/切片)从上到下的排列是这样的
当开始从 View 筛查的时候常常由于频繁的放大缩小到动作导致之前分析过并得到结论的内容被忘记
如此就可以找到相对加载时间较长的 View , 进而可以做出相应的优化
Debug.startMethodTracing("tomyangming.trace")
Trace.beginSection("[email protected]")
Trace.endSection()
Debug.stopMethodTracing()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.