ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Android Framework学习路线:从Binder到SystemServer的系统进阶指南

Android Framework学习路线:从Binder到SystemServer的系统进阶指南 经常有做了两三年应用开发的同事跑过来问我“我想转系统组framework到底怎么学”这个问题一问出来十有八九他还没搞清楚framework这个词到底指哪一块代码。有人以为是Android Studio里那一堆gradle插件有人以为是那些带hide注解的类还有人直接在手机上开个“显示布局边界”就觉得自己在研究framework了。这事不能怪大家。Android官方的层级图画得很漂亮但真正落到代码上“framework”这个词的边界非常模糊。它可以小到只指framework.jar里那几千个Java类大到包含AOSP里从内核驱动到应用框架的全部内容。而网上各种资料又特别喜欢把“Binder”“Handler”“AMS”“WMS”“SurfaceFlinger”塞进一个标题里搞得像背完八股就能通一样。实际上framework学习最大的门槛不是智商而是不知道从哪里下手以及不知道学到什么程度算“会了”。这篇文章我想站在一个真正做过系统定制和framework开发的工程师角度把整条学习路径拆开讲清楚。不讲那种“第一天看Java、第二天看C、第三天看内核”的鸡汤路线而是告诉你哪些是必须先啃下来的硬骨头哪些是可以先用工具绕开的坑以及你每天在应用层写的那些代码在framework里到底经历了什么。内容会比较长建议收藏之后分段看。1. 先搞懂Android framework到底是什么1.1 应用开发者和系统工程师嘴里的“framework”不是同一个东西如果你一直在写应用层你对framework的认知大概率是“系统提供给我调用的那些API”——getSystemService()、startActivity()、onCreate()这些。站在这个角度framework就是你Android Studio里自动补全的那些类的总和。这个理解没有错但它只讲清楚了“使用者”视角。真正的framework在AOSP源码里指的是从system_server进程往下到app进程之间那一大坨运行时代码。它包含两个大块一块是运行在你应用进程里的framework.jar比如ActivityThread、Looper、Handler、ContextImpl另一块是运行在独立系统进程里的各种XXXService比如ActivityTaskManagerService简称ATMS、WindowManagerServiceWMS、PackageManagerServicePMS。这两块之间靠Binder通信靠Handler做线程切换靠各种dispatcher派发事件。用餐厅打比方你的App是客人framework.jar里的ActivityThread是服务员系统和各种服务是后厨。客人只需要跟服务员点菜服务员负责把菜单传给后厨后厨做完了再通过传菜窗口把菜送出来。中间传菜窗口就是Binder负责跨进程搬运数据而后厨的厨师之间也有各自的规矩——谁先炒、谁后炒这就是各种Service之间的调度逻辑。很多人学framework只盯着Activity生命周期、Context机制这是只看到了传菜窗口的“菜”没看到后厨怎么运作。我见过不少应用开发转岗面试问startActivity启动流程能背出ActivityThread和AMS但一问他system_server里还跑着哪些线程、PMS负责干什么、WMS和ATMS之间怎么配合就答不上来了。这不是“知道”这是“背脚本”。1.2 哪些能力才算真正意义上的framework核心如果把framework比作一棵树真正的主干其实就那么几块Binder整个Android的跨进程通信骨架。没有BinderActivity调Service、App调系统服务全部瘫痪。Handler/Looper/MessageQueue单线程模型下的消息循环机制是system_server和应用主线程得以运转的基础。SystemServer系统服务的启动器所有核心服务都在这一个进程里创建。四大组件调度AMS/ATMS如何管理Activity任务栈Service怎么启动绑定BroadcastReceiver如何广播分发ContentProvider如何跨进程访问。View体系与WMS一个View如何被测量、布局、绘制最后通过WindowManagerService和SurfaceFlinger显示到屏幕上。输入系统从触摸屏到InputDispatcher再到目标窗口的整条链路。HAL与内核接口framework和硬件打交道的那层抽象包含Audio、Camera、Sensor、Graphics等。这些里面Binder和Handler属于“内功”必须精读源码SystemServer和AMS属于“骨架”要能画出调用链View、WMS、SurfaceFlinger属于“表现层”重点理解流程不需要逐行背诵HAL则偏向驱动适配适合走系统定制方向的人深挖。我个人的建议是不要一上来就捧着《Android内部机制》之类的书从头翻到尾。framework源码是一棵巨大的树不是一本需要顺序阅读的书你要做的是顺着某一条具体行为的“调用链”去探索。比如从一次点击屏幕到界面响应的完整链路或者从调用startActivity()到新界面显示出来的完整链路。一条链走通之后你会发现很多知识点都是围绕这条链展开的。2. 从应用层到系统层一条可执行的学习路线2.1 第一阶段先确认应用层基本功没短板这是一个看上去很废话但最容易翻车的建议。framework学习最怕的不是你不会底层而是你对上层理解有偏差。比如你连Activity的四种启动模式都说不清楚那就别指望能理解任务栈你连Handler的同步屏障和IdleHandler都没用过那就别指望能看懂Choreographer的帧刷新机制。这个阶段你不需要看任何系统源码只需要拿Android Studio做几件事写一个小Demo用ActivityManager的getRunningTasks()注意高版本需要权限或dumpsys activity activities观察Activity堆栈变化体会不同launchMode的实际效果。用android:process:remote开一个子进程在Application和Activity里各加一句日志你会直观感受到多进程下的Application初始化以及Binder跨进程调用时的耗时。手动模拟主线程耗时阻塞然后观察ANR弹窗的出现和/data/anr/目录下的日志这能帮你建立对“主线程消息循环”的敏感度。这些实验都不需要读源码但它们能帮你建立正确的“直觉”。有了直觉后面读源码时你才知道这段代码在真实运行时解决什么问题。另外提醒一句网上那些“两小时搞定Android framework面试”的文章你当索引目录看就行千万别当学习材料。真正搞懂framework至少需要你在一段时间内每天花两三个小时持续投入没有捷径。2.2 第二阶段把源码环境准备好并学会用正确方式“读”源码读framework源码第一件事不是下载源码而是想清楚用什么方式读。我见过最惨痛的案例有人辛辛苦苦下完整套AOSP几百个G最后因为编译环境问题卡了两个星期连framework.jar的影子都没看到信心直接没了。如果只是想理解逻辑我的建议是分两步走。第一步先直接用网页版源码查看器比如Android官方源码搜索网站cs.android.com配合Google搜索定位类名和方法名非常快。第二次再考虑拉AOSP代码到本地用aidegen生成索引然后导入Android Studio进行代码跳转和调试。本地源码我目前的推荐分支是android-13.0.0_r*或android-14.0.0_r*这两个版本代码结构清晰网上现成的调试方案也多。下载源码前先配好repo工具然后用镜像站同步。磁盘空间至少准备200G编译环境推荐Ubuntu 20.04以上内存16G起步、32G比较舒服。源码下载完别急着编译先做一件性价比极高的事打开frameworks/base/core/java/android/app/ActivityThread.java搜main方法然后从这个入口开始追。ActivityThread是每个应用进程的入口从main()到attach()再到handleBindApplication()这条线上基本覆盖了“一个App进程是怎么活起来”的全部答案。读的时候记住一个原则不要逐行读要“带问题读”。比如你问“Application和Activity的onCreate谁先执行”然后带着这个问题去追调用链从ActivityThread.performLaunchActivity()里你会看到appContext先创建、Instrumentation.callApplicationOnCreate()后调用的顺序。这个过程远比背文字更有用。2.3 第三阶段Binder和Handler是绕不过去的两座山如果让我只选两个topic作为framework的“生死线”那就是Binder和Handler。这两个东西不理解透后面看AMS、WMS、SurfaceFlinger全是糊涂账。先说Binder。你要理解的不是“Binder是Android的IPC机制”这种一句话答案而是四个层次第一层进程隔离与地址空间。每个进程有自己的虚拟地址空间用户空间不能直接访问别的进程的数据这是Binder存在的底层原因。第二层Binder的通信模型。Binder把一次跨进程调用抽象成Client、Server、ServiceManager也叫ContextManager三方的协作Server启动后向ServiceManager注册自己Client通过ServiceManager查到Server的代理然后通过这个代理发起调用。Android里面各种getSystemService()查的其实就是服务列表代理对象是BinderProxy真实对象叫Binder或其内部类BBinder的Java层代表。第三层一次拷贝原理。Binder在底层用mmap把内核缓冲区映射到用户空间所以一次数据传输只需要从发送方拷贝到内核缓冲区接收方直接通过映射读取相比传统的Socket/管道两次拷贝少了一次。这是Binder性能优于其他IPC的关键原因面试必问。第四层线程池机制。Binder是支持并发调用的每个进程在初始化时会创建Binder线程池默认是15个线程部分版本可配置远程调用请求到达后会从池中取一个线程来执行。理解这点你才能回答“system_server为什么有那么多binder线程”这种问题。再说Handler。Handler的本质不是“异步”而是“把一段逻辑放到指定线程的消息队列里等待执行”。它由Looper循环器、MessageQueue消息队列、Handler处理器组成。MessageQueue.next()在无消息时会通过epoll阻塞让线程休眠有消息时再唤醒。这就解释了为什么主线程平时不占CPU但又能及时响应事件。读Handler源码时我建议重点看MessageQueue.java的next()方法里面涉及nativePollOnce的调用这是理解Block和Wakeup的关键。然后看Handler.enqueueMessage()和dispatchMessage()理解消息从入队到分发的全流程。最后再看Choreographer和ViewRootImpl了解一帧的绘制消息是怎么被安排到主线程队列里的。当你把Binder和Handler理解成“两条腿”后再去看AMS调度Activity、WMS调度Window、Input系统调度事件会发现所有逻辑都是在这两条腿上跑的。2.4 第四阶段从SystemServer到HAL、SurfaceFlinger、perfetto基础内功扎实之后就该往系统层面扩展了。这个阶段我建议按三个方向深入但没必要三个都学根据你想走的方向选就行方向A系统服务与AMS/ATMS调度。以startActivity()为线索从Instrumentation.execStartActivity()一路追到ATMS.startActivity()再追到ActivityStarter、Task、ActivityRecord这些数据结构。顺便把ActivityTaskManagerService和WindowManagerService的互相调用也看了理解Activity和Window的对应关系。方向B图形显示链路。这个方向会硬核很多。你要理解一张图片是怎么从App的Canvas绘制指令变成RenderThread的DisplayList再通过SurfaceFlinger进行合成最终通过HAL送到屏幕。重点关注ViewRootImpl.performTraversals()、ThreadedRenderer、SurfaceFlinger的合成流程以及Choreographer里面的vsync机制。学完这个方向性能优化和掉帧问题对你来说就是透明的。方向C硬件抽象与驱动适配。HAL是连接framework和内核的桥梁。比如音频上层Java通过AudioFlinger和AudioPolicyService管理音频策略底层通过HAL中的audio_hw实现具体设备的读写再比如CameraHAL定义了CameraDevice、CaptureRequest的数据流模型。做手机厂商或车载系统定制这个方向需求量很大。另外性能分析工具perfetto强烈建议在这个阶段系统性学一遍。它是目前Android上最强大的系统级trace工具可以同时记录CPU调度、进程/线程状态、Binder调用、SurfaceFlinger合成、内存分配等信息导出后能直接在网页上可视化。调试framework问题时它比logcat高效十倍。抓trace的基础命令很简单# 抓取10秒系统全局trace adb shell perfetto -o /data/misc/perfetto-traces/trace.perfetto -t 10s sched freq idle binder_driver gfx view wm am # 将trace文件拉到本地 adb pull /data/misc/perfetto-traces/trace.perfetto # 打开ui.perfetto.dev加载文件即可查看看到这里你应该明白了framework学习不是“看一本书”的事它是“建立一棵知识树”的事。Binder和Handler是根SystemServer是主杆AMS/WMS/View是枝干HAL和图形链路是叶。根不牢枝干全是空中楼阁。3. 实战拆解一次点击背后framework到底干了多少活3.1 SystemServer启动流程系统服务的“开国大典”要理解framework绕不开SystemServer。它是所有核心系统服务的老家位列Android启动顺序中最关键的一环。整体启动链路是init进程 →zygote进程 →SystemServer进程。zygote是Android的“进程孵化器”App进程和SystemServer都由它fork而来。SystemServer会在main()方法里调用SystemServer.run()然后在其中分三批启动所有服务引导服务Boot Services包括ActivityTaskManagerService、PowerManagerService、PackageManagerService等它们是最底层的依赖。核心服务Core Services包括BatteryService、UsageStatsService、WebViewUpdateService等。其他服务Other Services包括AudioService、CameraService、AlarmManagerService、NotificationManagerService、WallpaperManagerService等。现在Android版本中ATMS和WMS是前后脚创建的它们俩共享同一个WindowManagerGlobalLock这解决了很多历史性的死锁问题。如果你想在系统启动时观察服务创建顺序可以直接抓logcat看SystemServiceManager.startService()的日志系统会打印类似Starting service XxxService的信息。这一段学习的具体目标是能自己画出这张表服务名职责启动阶段ActivityTaskManagerService管理Activity、任务栈引导服务WindowManagerService管理窗口、布局和输入窗口焦点引导服务PackageManagerService包管理、权限管理引导服务PowerManagerService电源和唤醒锁管理引导服务AudioService音频策略、音量、设备路由其他服务CameraService相机设备和采集流程其他服务3.2 startActivity的完整旅程跨进程调用的样板案例从你点击桌面图标到Activity界面显示这个过程中framework的参与堪称“接力赛”。我用一个简化的链路拆解它第一步你的App进程发起调用。应用内调用startActivity()实际会走Instrumentation.execStartActivity()通过ActivityManager.getService()获取ATMS的Binder代理然后发起跨进程调用。这里注意底层是ActivityManagerService在Android 10以后把Activity相关的逻辑拆分到了ActivityTaskManagerService所以现在真正干活的是ATMS。第二步system_server进程处理。ATMS收到调用请求后会通过ActivityStarter判断调用者的Intent是否合法、目标Activity是否存在、是否有权限然后计算目标Activity应该放入哪个Task、复用还是新建、使用什么启动模式。接下来会通过ActivityRecord表示目标Activity并通过TaskSnapshotController保存当前屏幕上旧Activity的快照方便做过渡动画。第三步通知App进程创建Activity。ATMS告诉目标App进程如果目标App还没启动则先通过ZygoteProcess请求Zygote fork出一个新进程让它执行ActivityThread的scheduleLaunchActivity()。注意这里的“告诉”也是Binder通信。第四步App进程内执行。ActivityThread收到消息后把LaunchActivity的消息发送到主线程Handler的MessageQueue中。主线程在消息循环里取出消息调用handleLaunchActivity()然后通过Instrumentation.newActivity()反射创建Activity对象接着performLaunchActivity()里做attach()、onCreate()、onStart()、onResume()等回调。最终ViewRootImpl会向WMS申请添加窗口完成界面显示。所以你发现没有Application层一个startActivity()背后经历了两次跨进程Binder调用和至少一次线程切换中间穿插着系统服务的各种调度。这还只是最简链路没算上ANR监控、GC干预、WindowToken校验这些细节。我在带新人的时候要求他们必须把这条链路的每一步对应到源码类名并且在源码里跳到真正的代码行能用文字描述出每一步发生了什么。能完整做到这件事framework才算是“入门了”。3.3 触摸事件变成界面反馈Input体系的工作现场触摸事件链路和Activity启动链路看起来完全不一样但骨架还是Binder Handler。物理触摸屏产生中断后内核驱动把原始事件上报给EventHub然后InputReader读取事件InputDispatcher负责分发。InputDispatcher会按窗口焦点选择目标窗口通过Binder把事件发送到目标App进程。App进程的InputEventReceiver收到事件后把它放入主线程队列最终传递给ViewRootImpl和DecorView由View数从根节点开始dispatchEvent分发到具体子View。这里有个很方便的观察手段在真机上开启“显示触摸位置”和“指针位置”同时打开开发者选项里的“系统跟踪”你就能在perfetto里看到从InputDispatcher到ViewRootImpl的完整调度。对于研究输入焦点和手势冲突这套方法非常有效。3.4 SurfaceFlinger和HAL最后一块拼图事件处理完UI要更新真正负责把UI画到屏幕上的是SurfaceFlinger。App进程通过Canvas绘制视图后会把渲染指令交给RenderThread通过OpenGL或Vulkan生成GPU缓冲区。SurfaceFlinger的作用是把多个App的缓冲区你看到的其实是多个Surface合成一帧画面再通过HAL里的DisplayDevice输出到屏幕。Android的刷新机制是垂直同步VSync驱动的。当屏幕刷新率达到120Hz时SurfaceFlinger每8.3ms消费一个新帧App的Choreographer也会根据VSync信号开始绘制新帧。如果App绘制耗时太长错过VSync就会出现掉帧也就是我们常说的卡顿。这里有一个面试常问的问题“为什么Android建议使用12ms/16ms作为帧耗时预算”其实这取决于屏幕刷新率。60Hz对应16.6ms90Hz对应11.1ms120Hz对应8.3ms。你平时用Choreographer打帧间隔或者用dumpsys gfxinfo查看帧耗时判断的就是这个预算有没有超支。SurfaceFlinger这层代码涉及大量C和GPU概念新手容易劝退。我的建议是先把握黑白灰框架先看BufferQueue的生产-消费模型再看SurfaceFlinger的onMessageInvalidate触发合成最后通过dumpsys SurfaceFlinger --latency这类指令感受帧率数据。别一上来啃RenderEngine的GLSL代码那不是新手的地盘。4. framework日常开发和调试的“保命工具”学framework是为了改framework改framework就离不开调试。这里分享几个我几乎每天都在用的工具和思路。4.1 日志三板斧logcat、dumpsys、perfetto让你不再当“盲人”framework系统服务里的日志输出非常丰富关键要会看。普通App开发通常只关心自己应用的tag但系统开发必须习惯从海量系统日志里捞关键信息。logcat最基础的。看system_server相关日志需要过滤SystemServer、ActivityTaskManager、WindowManager、ActivityManager这些tag。也可以配合adb logcat -b all查看所有缓冲区常用于分析ANR、系统服务崩溃。dumpsys这是framework的“体检报告”几乎每个系统服务都支持dumpsys命令输出该服务的内部状态。常用例子# 查看Activity任务栈详情 adb shell dumpsys activity activities # 查看窗口层级和焦点 adb shell dumpsys window windows # 查看进程和内存状态 adb shell dumpsys meminfo # 查看后台进程和LRU状态 adb shell dumpsys activity processes我经常用dumpsys activity activities判断一个Activity是否真的在预期任务栈里用dumpsys window windows判断弹窗窗口焦点问题。这两个命令能帮你快速定位很多崩溃和UI异常。perfetto前面已经提过这里再补充一个实操场景。如果你怀疑某个操作卡顿通常抓一次10秒trace就够了。重点看四个指标主线程和UI线程有没有被阻塞。是否有明显的高耗时函数perfetto会显示函数调用栈。Binder调用频率是不是过高导致系统服务线程池被打满。SurfaceFlinger有没有出现FrameMissed或Jank事件。perfetto的可视化页面支持自己添加Track比如CPU调度、锁竞争用顺手之后你会理解为什么做framework的人天天离不开它。4.2 动态调试system_server断点打在“系统心脏”上在改AMS/WMS这类系统服务逻辑时日志往往不够用你需要断点。如果你能编译AOSP并且有可root的设备或模拟器推荐用Android Studio的Attach Debugger to Android Process功能选择system_server进程。断点可以打在Java层的ActivityTaskManagerService.java里单步追踪Activity调度逻辑效果和普通App调试完全一样。如果设备没有root也可以用adb forward配合jdwp方式但限制比较多。还有一条路是用run-as针对可调试的App进程但system_server的调试通常还是需要root或eng版本系统。如果是C层的问题比如SurfaceFlinger、Binder驱动那就得上gallium工具或者lldb。但这个学习曲线比较陡没有Java层那么好上手新手阶段可以先绕开。4.3 系统定制常用操作改framework.jar后如何让它生效改完framework代码总得跑起来验证。常见做法是编译整个系统然后刷机但这样太慢。更高效的做法# 1. 关闭selinux开发机常用如果用eng版系统则默认关闭 adb root adb shell setenforce 0 # 2. remount系统分区 adb remount # 3. 把编译出来的framework.jar推到系统目录 adb push out/target/product/xxx/system/framework/framework.jar /system/framework/ # 4. 重启 adb reboot注意现在分区格式普遍是动态分区或super分区adb remount不一定有效需要先adb disable-verity再重启。另外修改framework.jar后有可能还需要更新boot.art、boot.oat等优化文件否则运行时可能走旧缓存。稳妥的办法是直接adb shell cmd package compile -m speed -f android重新编译一下或者干脆刷system.img。如果你只是改系统属性、权限配置这类轻量改动完全没必要动framework.jar可以用adb shell setprop临时设置或者pushsystem/etc/permissions下的xml来扩展权限。学会区分“改框架代码”和“改配置”哪个成本更低是系统开发的基本素养。5. 面试和实战中反复出现的framework高频考点5.1 经典问题速查这部分整理一份我面试候选人和自己被面试时都被问过的高频列表每一条背后都能展开成一篇长文这里只给关键思路方便你自查。问题核心答题要点Binder为什么比Socket快一次拷贝 mmap内核态映射Socket需要两次拷贝Handler的IdleHandler有什么用空闲时执行常用于延迟加载、埋点、GC时机优化AMS和ATMS有什么区别Android 10后拆分ATMS负责Activity/任务栈AMS负责权限、进程、生命周期管理ViewRootImpl和DecorView什么关系DecorView是顶级ViewViewRootImpl是View树与WMS沟通的桥梁负责performTraversals调度SurfaceView为什么能独立线程绘制独立Surface和BufferQueue在WMS上拥有独立窗口不参与宿主View的绘制链表WMS和Window的关系Window是抽象概念WMS管理Window的添加、层级、焦点、布局每个Window对应一个ViewRootImpl系统启动时为什么zygote要先加载framework共享框架类fork出的App进程能快速复用类加载结果节省内存和时间SystemServer为什么不开多个进程降低进程间通信开销用binder线程池和高性能设备承载并发代价是单点风险所以有watchdog这些问题的回答都需要你能“讲出过程”而不是“报出名词”。比如Binder为什么快你要能把copy_from_user和mmap的链路讲清楚Handler的IdleHandler要能说出MessageQueue.next()在取消息阻塞前会执行mIdleHandlers里的任务。5.2 容易踩坑的细节framework面试除了问原理还喜欢埋一些“看似简单但你不动手真不知道”的细节。比如Binder线程池默认大小Android 8.0以后默认BINDER_MAX_THREADS是15但某些系统服务创建时会手动调大比如系统UI。用dumpsys activity能看到binder线程状态。system_server里Handler的线程与优先级system_server的ui线程负责主消息循环android.io线程负责文件/网络IObinder线程处理远程调用。如果某个服务死锁多数是binder线程互相等待。Apex模块和普通jar包的区别Android 10以后引入APEX机制像com.android.runtime、com.android.art这些都是APE模块可以独立升级。framework.jar还在system/framework但被拆出的模块越来越多了。多应用同时录音的限制Android 9之前音频录制策略是排他式的之后在高通/MTK平台实现了多应用混音但应用层仍需要处理AudioRecord的并发策略。这些细节单看八股文背不下来都是动手改过framework或修过系统bug才能积累出来的。所以面试时如果被问到能结合一个真实案例讲出来会比背答案强十倍。6. 学习framework最容易踩的坑与我个人的一点经验最后聊几个几乎所有自学者都会遇到的问题。第一个坑试图“读完全部源码”。AOSP光frameworks/base就有几百万行代码你不可能逐行读完。正确的方式是围着一条条“调用链”打转。今天追一遍startActivity()明天追一遍requestLayout()后天追一遍InputDispatcher链与链之间自然交织出知识网。第二个坑环境搭好了却没坚持下来。我见过有人源码下载了一个月天天问“编不过怎么办”最后代码看了不到十行。人的意志力非常有限与其花精力折腾编译环境不如先用cs.android.com在网上读代码。等你真的把Java层核心链路读完后再决定要不要下源码本地编译。把技术难度嚼碎了再啃效率高得多。第三个坑只啃Java层对C和底层避之不及。理解Binder离不开C的ProcessState、IPCThreadState理解SurfaceFlinger离不开Layer和BufferQueue的C实现。如果你只盯着Java层很多“性能问题”“卡顿问题”永远解释不了。当然不要求你达到C专家的水平但至少能读懂关键函数和结构体。第四个坑不看日志瞎猜。framework问题定位绝大多数是靠日志和trace不是靠逻辑推理。遇到系统服务崩溃先adb logcat -b crash看栈遇到卡顿先抓perfetto看关键线程遇到显示问题先dumpsys window看窗口状态。有了数据再推测原因基本一两轮就能锁定。我自己的习惯是书房白板上永远写着两条主线一条是Binder一条是Handler其他所有知识点都被我挂在它们下面。每次被一个新问题卡住我就先问自己这个问题涉及的是哪一个Binder接口它跑在哪个线程的哪个Handler消息里想清楚这两件事八成问题已经有了方向。如果你也准备走这条路我的建议很朴素给自己定一个为期三个月的计划每周只学一个主题每个主题都要求自己能动手写一个小Demo或画出一张调用链图。三个月下来你再看Android系统绝对不会是当初那个只看得见API的黑盒了。
返回列表