— Android蕴藏了深刻的架构思路和精致的系统机制
— 外行人看熱鬧,內行人看門道;本课程陪你看Android的設計門道
— Android就像一匹马,如果你愿意摸牠、陪牠、爱牠、欣赏牠的话,则本课程是你的最佳选择
课程说明:如何掌握Android架构的知识体系呢?
欲掌握Android的知识体系,从框架角度切入,可以找到它的甜心点(Sweet Spot)。由于它是一个开源开放的架构,我们可以直接切入核心,看到树干结构,一目了然;而不必像iOS、Win8等封闭平台,只能从外部功能(树叶)去猜测底层架构。所以,欲掌握Android架构体系,从它的多层框架体系视角切入,是最有效的途径。其框架体系如下:
图-a1. Android的多层框架体系
基于这个框架体系,再将众多功能(子系统)的模块添挂上去,每一项子系统就如同一棵完整的树,有树叶、树干、树根等。例如,MediaPlayer播放功能,就含有Java、JNI、系统服务、HAL等完整的体系(即一棵完整的树);如下图所示:
图-a2. Android平台就像一座森林,由很多棵树所组成
Android就如同一座森林,由Bluetooth、MediaPlayer等众多的树所组成的。上图看来是蛮有规律的,然而更具规律性的是:各层框架的基本元素,其代码造形(Form)是一致的,如下图:
图-a3. 以<EIT造形>去看各层框架
例如,在Activity-View架构看似很复杂,其实只是两个主要的EIT代码造形所组合而成的。如下图所示:
图-a4. 基于简单造形,去掌握复杂的架构
俗语说,内行人看门道;专业的视角、专业的造形(Form)和模式(Pattern)就是其中之道。在本课程里,将带领大家以内行人的视角,来解析Android的架构和机制。此外,在解析既有框架之际,也能深刻理解这些造形或模式的使用绝窍,未来便能结合行业别领域知识,轻易开发出行业型应用框架了。
课程大綱:
内容
Sec-1. 看待Android架构的十个新视角
Sec-2. 从接口(Interface)出发
Sec-3. Android的多层框架体系
Sec-4. Android架构里的重要机制
Sec-5. Java层框架解析
Sec-6. Java与C/C++整合开发技术
Sec-7. UI框架解析与应用界面设计
Sec-8. 以EIT造形解析复杂的框架机制
Sec-9. 跨平台模式:一个造形,三个策略
Sec-10. <Android + 敏捷>以及落地问题
Sec-1. 看待Android架构的十个新视角
大家都知道,创新不一定要去发明全新的东西,变换一些全新视角(View)来看原有事物,做不一样的联想、以新的连结&组合,做为新产品的独特架构,只要能更贴近用户的需要和口味,就能创造获利机会。Android设备愈来愈多、百花齐放,提供了无限大的组合创新空间;记得,变换观点、独特组合、贴近用户、努力经营,就能捕捉到好机运;千载难逢的好机会,不要错过。
大家都会希望能愈流畅地变换新视角,但却往往被自己内心深处的假设(Assumption)所局限了。尤其,有许多内心的假设,是连自己都不自觉的、长久以来都信以为真(理)的,未曾质疑过它;从现在开始,试着经常反思内心的假设,审视它、放宽它,新视角就出现了,商机也就浮现出来了。关于反思内心的假设,可参考:”高老师的设计思考三部曲”。 在本课程里,将与您一起变换视角;一方面反思你内心深处的假设,一方面变换出十个新视角,来重新看看你已经很熟悉的Android系统架构。这十个新视角如下:
1.1 API = 话语权
◆ 在Android 潮流下,商业成功的钥匙就藏在API隙缝中
◆ 全面性理解框架API,即能拥有成功密码、造就天使,并成为商业竞争下的赢家
◆ 对API拥有主导权,就能在商业上获得主导地位,就会是赢家。
◆ API与UI不同
◆ UI是App与用户的交互接口
◆ API则泛指软件模块间的接口,可分为:
SI:本架构与外部系统之间的接口
PI:本架构与内部挿件(Plug-in)之间的接口
一般API:本架构与应用程序(App)之间的接口
◆ 掌握API定义权,就拥有话语权(主导权)
1.2 应用框架:用来框住应用(App)的架构
◆ 框架的基本组成元素:EIT代码造形(Form)
◆ 造形的<I>就是API
◆ 框架是鱼饵,API是鱼钩
◆ 鱼饵是送人的礼物;送越多,拥有市场版图越大
1.3 框架调用App,不是App调用框架
◆ 用户没有直接碰触软件(App)
◆ 用户碰触的都是硬件
◆ 硬件通知框架,框架调用App
1.4 JNI: C调用Java,不是Java调用C
◆ Java层的框架(基类)是送人的礼物
◆ 所以关键模块,以及控制点必须放在C/C++层
◆ 控制点透过JNI控制Java层的框架(基类),基类控制App
1.5 重视跨平台设计,才能建立自己平台
◆ 必须使用别人芯片平台,如何能摆脱别人的牵绊?
◆ 必须使用Android软件平台,如何协天子(Android)以令诸侯?
◆ 如何跨越Android的版本升级和碎片化障碍?
◆ 应用软件如何跨<操作系统>平台(如Android、iOS等)呢?
◆ 互联网&电信厂商如何追求跨终端平台(如TV, Pad等)?
◆ 终端产品如何云端(Cloud)平台?
1.6 没钱就改版,改版就有钱
◆ 终端厂商的底层软&硬件模块变动自由度非常重要
◆ 如此,创造”没钱就改版,改版就有钱”的机会
◆ 上层模块不能要求底层的稳定不变,而是要处处维护底层变动自由度
1.7 软硬整合开发,硬硬结合销售
◆ 如苹果公司的主(大)硬件种类不多,但其(小)配件总类多达600多种
◆ 软硬整合能涵盖大、小硬件整合一起销售
◆ 小配件的短期获利,能调降主硬件售价,扩大市场地盘
1.8 质量保证 = 跨平台架构设计+测试
◆ 系统架构设计与测试两者携手,一起摆脱别人平台的牵绊,然后提高质量,振翅高飞
◆ 检验别人(平台)软、硬件模块的功能
◆ 测试您自己(平台)软、硬件模块的功能
◆ 测试您的软硬整合平台框架&API
◆ 测试您自己的应用(App)程序代码
◆ 测试UI体验(look and feel)
1.9 项目管理:可以搭配敏捷(Agile)开发
◆ 为什么敏捷开发与Android是个很好的搭配呢?
◆ 理由(一):Android有测试框架,可建立TDD测试机制来推动迭代过程
◆ 理由(二):Android框架内涵是代码,满足敏捷原则:”各项设计必须迅速落实为代码”,这很有利于密切配合敏捷迭代过程,并漂亮地”落地”在Android平台上
1.10 未来性:以软件接口包装通信协议
◆ 通信协议的善变是本质性的
◆ 软件接口可以包容善变的协议
◆ 例如,以软件的Socket接口包装Zigbee或Bluetooth的善变性
Sec-2: 从接口(Interface)出发
2.1 设计概念与技艺
◆ 阐述应用框架魅力的泉源:控制反转(IoC, Inversion of Control)机制
◆ 深入认识控制反转机制
◆ 主控者是框架,而不是应用程序
◆ 框架的重要功能:提供默认行为(Default Behavior)
◆ 善用类的继承(Inheritance)机制
◆ 设计基类的抽象函数
◆ 抽象是手段,组合是目的
2.2 框架设计的需求分析方法
◆ 基本设计技能:把轮胎拔掉
◆ 伟大的雕刻师罗丹( Musée Rodin)说:”把不必要的部分去掉”
◆ 买主需求:想想为什么(why)汽车架构师会决定把轮胎拔掉呢? 其背后的理由是:买主来了,才知道买主对轮胎的偏好或特殊需求。只有等到买主决定和挑选了轮胎之后,才能将轮胎装配上去。
◆ 探索买主需求
★ 为什么把轮胎拔掉呢?
★ 为什么火锅店的桌子要挖洞呢?
★ 为什么餐厅要分开<食谱>与<点菜单>呢?
2.3 接口设计与EIT造形
如何定义接口(Interface)
◆ 在OOP里,将接口定义为一种特殊的类别(Class)
◆ 在Java里,将”纯粹抽象类别”称为接口(Interface)
◆ EIT造形的接口表示为<I>
◆ <I>可以合并到<E>里
◆ 复习UI与API
◆ 被动型API与主动型API
API与商业模式
◆ API决定控制权
◆ 谁拥用接口的制定权,谁就掌握控制点,就能获得较大的话语权
◆ 从API看控制力量的强弱等级
EIT基础(一):容易,插件容纳变化
◆ 什么是插件<T>?
◆ 插件的分类
◆ 插件与接口
◆ EIT造形里的插件<T>
EIT基础(二):结构制约,积极掌控插件
◆ 什么是接口<I>?
◆ 谁控制<I>?
◆ 接口的分类
◆ <I>决定控制权
◆ 没钱就改版,改版就有钱
EIT基础(三):组合创新,让整体<飞>起来
◆ 什么是平台<E>?
◆ <E>+<I> = 框架(Framework)
◆ <E>是控制点,透过<I>来驱动<T>
Sec-3. Android的多层框架体系
3.1 Android的分层框架
◆ HTML5/JavaScript层
★ 创造跨平台的HTML5/JS层
★ 这透过WebView呼叫下层的Java插件(属于Java层)
◆ Java层
★ 这是专属于Android平台的App
★ 透过JNI呼叫本地C函数(属于本地C层)
◆ JNI / C层
★ 能透过ServiceManager绑定下层的C++核心服务
★ 也能直接呼叫HAL-based驱动模块
◆ 核心(系统)服务层
★ 直接呼叫下层的HAL-based驱动模块
★ 也能将讯息传送给上层本地C模块
★ 核心服务也能以Java来撰写,这种核心服务属于Java层
◆ HAL & 驱动层
★ 为了避开GPL协议,Android驱动大多写成HAL Stub模块
★ HAL Stub可透过System Call呼叫Linux内核,实际控制硬件
3.2 观摩MediaPlayer多层框架(子)体系
◆ Java层框架基类及相关类别
◆ JNI界面
◆ Mediaplayer的C++层服务 & 驱动层
3.3 观摩Camera多层框架(子)体系
◆ Java层框架基类及相关类别
◆ JNI界面
◆ Camera的C++层服务 & 驱动层
Sec-4. Android架构里的重要机制
4.1 Android是如何启动的?
◆ Init进程
◆ Init创建ServiceManager和Zygote进程
◆ 由Zygote创建VM(Virtual Machine)和SystemServer进程
4.2 线程模式
◆ Android的主线程(Main Thread)
◆ 主线程与ANR(Android Not Responding)对话框
◆ 如何诞生Java层子线程
◆ Java层主、子线程的通讯模式
4.3 安全机制
◆ Android/Linux的UID观念
◆ Android的Permissions机制
4.4 跨进程(IPC)机制
◆ Android 的IPC幕后设计:BD(Binder Driver)驱动架构
◆ 以IBinder接口包装BD驱动的服务
◆ 包装IBinder接口的Proxy-Stub设计模式
◆ Proxy和Stub类别的代码
◆ 设计Proxy和Stub类别的API
◆ 如何自动生成Proxy和Stub类别代码
Sec-5. Java层框架解析
5.1 Java层框架介绍
◆ 常用的服务
★ 简介(Overview)
★ Android各项服务的启动
★ Windows Manager
★ Activity Manager
★ Package Manager
★ 其它服务介绍
◆ Android框架四大基本组件:Activity, Service, Broadcast Receiver与ContentProvider
通信基础:Intent
★ Intent-based Programming
★ 范例:使用Intent启动Activity
Activity
★ 使用Intent启动Activity
★ Activity的life-cycle
★ Activity间的互相传递数据
★ 建立多Activity的应用程序
★ Android基本UI布局及样式(Pattern)
Service
★ 使用Intent启动Service
★ 何谓远距(remote)的Service?
★ 绑定(bind)远距Service
★ 建立Service应用程序,以播放背景MP3歌曲
BroadcastReceiver
★ 何谓BroadcastReceiver?
★ 以BroadcastReceiver接收SMS短信
★ 建立BroadcastReceiver应用程序,以启动Service播放MP3歌曲
ContentProvider
★ 何谓ContentProvider?
★ ContentProvier与SQLite数据库
★ 使用ContentProvider进行数据的增、删、改、查。
5.2 Java层的跨进程(IPC)机制
◆ Activity使用IBinder接口调用远程的Service
◆ IBinder接口& AIDL方法
★ 方法(一):Implementing a Binder
★ 方法(二):Using a Messenger
★ 方法(三):Bound Services
Sec-6. Java与C/C++整合开发技术
6.1 JNI Native进阶开发:雕龙妙技
◆ 控制点的抉择
★ 控制点的规划
★ 控制点在Java层:复习Java呼叫Native C函数
★ 控制点在C/C++:Native C如何呼叫Java函数
★ 控制点在C/C++:Native C函数如何诞生Java对象
◆ JNI Native C的线程模式
★ Android VM的线程模式介绍
★ JNI Native C程序的线程模式
★ JNI Native程序的线程安全设计
6.2 核心服务框架的关键机制:Binder Kernel
◆ 认识Android核心服务
★ 以多媒体Mediaplayer为例介绍C++层服务
★ 核心服务:包括Android Service和 Native Service
★ 核心服务的幕后机制:Binder Kernel
◆ 核心服务框架内的通讯机制
★ IPC跨进程(Process)通讯机制
★ 如何绑定(Bind)C++层服务
6.3 撰写你的第一个Android核心服务
◆ 观摩天字第一号核心服务:SM(ServiceManager)
◆ 撰写C++类实现你的核心服务
◆ 创建该C++类的对象,由SM存入Binder Kernel里
◆ JNI函数透过SM来绑定该核心服务
◆ Java框架透过JNI而呼叫核心服务
◆ 核心服务透过HAL衔接到Linux或底层驱动程序
Sec-7. UI框架解析与应用界面设计
7.1 解析UI框架的线程机制
◆ Activity与View 控件体系的事件(信息)传递机制
◆ View 控件体系的扩充与组件定制
◆ SurfaceView控件幕后的多线程机制
◆ 采用EIT,亲自设计游戏循环:活用线程模式
7.2 UI框架与画面布局
◆ 复习UI线程及线程安全
◆ View类别体系的常用控件
◆ 布局、菜单、对话框
◆ GroupView与Layout
◆ ListView与活用Adapter
◆ UI Style初步与活用
◆ UI 布景(Theme)设计
◆ 以XML定义UI Layout设计
7.3 UI呈现与多媒体框架解析
◆ UI界面与绘图应用
★ Android 的2D绘图基础:使用Skia
★ 活用Android的View控件及其画布(Canvas)
★ 使用Android的Drawable图像资源
★ Drawable图像的透明度
★ Android的3D绘图基础:使用OpenGL ES
★ 介绍Android的SurfaceView控件
★ 范例:让图像在SurfaceView里旋转
◆ SQlite数据与多媒体应用范例
★ 存取SQlite数据库
★ 规划音乐档案格式(WAV)
★ 启动Audio 服务进行录制音乐,并存入SQlite数据库
Sec-8. 以EIT造形解析复杂的框架机制
8.1 解析UI框架幕后的服务机制
◆ SurfaceView框架范例解析
★ 一般View与SurfaceView的区别
★ SurfaceView的执行绪模式
★ 以OpenGL_ES说明SurfaceView的JNI接口设计
◆ SurfaceFlinger在框架里的角色
★ SurfaceFlinger的任务
★ SurfaceView如何透过JNI呼叫SurfaceFlinger核心服务
★ SurfaceFlinger核心服务如何整合多个SurfaceView的动画
8.2 解析JUnit测试框架和机制
◆ Android的测试工具,都是基于JUnit测试框架的
◆ JUnit框架也是由许多EIT造形所组成;其TestCase基类是<E&I>
◆ 从基类衍生出各子类,如ServiceTestCase就是扩充的<E&I>;其内涵的setUP()和tearDown()函数就是<I>
◆ 可撰写<T>(即Test case)代码,来启动TDD机制
◆ 可使用TestSuite基类来管理一群相关的<T>(即Test case)
8.3 解析Android的ListView框架
◆ 请您观摩ListView的框架,解析其幕后的EIT造形,理解其插件<T>如何容纳用户(App)的变化
◆ Step-1:需求分析,解析用户需求变化
◆ Step-2:依据需求分析表,设计接口<I>
◆ Step-3:详细设计接口<I>和插件<T>
◆ Step-4:将EIT造形对映到Android的程序码
8.4 Slot Machine游戏机的情境,设计您的造形
◆ 分析情境
★ 用户(User)是:玩家
★ 买主(Buyer)是:赌场老板
★ (前端)游戏机制造商(Maker)是:G公司
◆ 分析买主需求的变化
★ 变化(一):选择赌场的后端Console平台
★ 变化(二):自订UI
★ 变化(三):修正奖金
◆ 依循EIT造形,规划您的<E&I>,并设计<T>来吸纳买主的变化
8.5 解析UI的复杂<Context-View>框架
◆ 情境:Android如何播放MP4影片
◆ 解析架构,其含有3个EIT造形
★ 造形-1:{ ViewRoot,View, SurfaceView }
★ 造形-2:{ SurfaceView,Callback, <T> }
★ 造形-3:{ ActivityThread,Activity, <T> }
◆ 并使用到一个外来的平台:MediaPlayer播放器
Sec-9. 跨平台模式:一个造形,三个策略
9.1 一个造形,三个策略,巧妙组合出无限风格
◆ 在别人的平台上,受制于人,因而有”跨平台”的期盼
◆ 于是,展开了:争夺<I>制定权,以及逻辑<E>控制权
◆ 尚方宝剑:一个造形,三个策略
◆ 一个造形:EIT造形
◆ 三个策略
★ 策略-1:把它”EIT(设计)”了
★ 策略-2:挟天子以令诸侯
★ 策略-3:建立中间件(middleware)
◆ 众多风格:策略的变化与组合
9.2 跨芯片(小)平台:采取<策略-1>
情境A:先有别人的(小)平台,然后才建立我的平台
◆ 小平台是指别人的平台,该平台的变化决定于别人
◆ 为了跨平台,就不宜直接使用别人的平台
◆ 您设计<E&I>,而且设计<T>来包容别人平台的变化,这就称为:把它”EIT(设计)”了。
情境B:先建立我的平台,然后才让别人来扩充(Extend)
◆ 这反过来,让别人设计插件<T>来扩充(extend)您的<E&I>
◆ 别人为了保护他自己,也会将插件分成两部分:<壁虎尾巴>与<壁虎身体>
◆ 万一您的<E&I>有变化时,这只壁虎(插件)便能弃尾求生,让<壁虎身体>跨您的<E&I>
9.3 跨Android版本(大)平台:采取<策略-2>
◆ Android升级和版本变更频繁,终端必须随之而更新
◆ Android是一个多层级<E&I>结构,各层都是由Google所开发,Google是强龙,位居天子角色,其设计<I>来控制您的插件<T>
◆ 您可以拿EIT造形搭配Proxy-Stub设计模式,规划Stub类别(曹操类),制定自己的<I>,让<T>脱离Android的<E&I>所牵制;实现”挟天子以令诸侯”的效果
9.4 跨自己的平台:采取<策略-3>
◆ 随着您的公司业务成长,您的平台版本变更频繁;如何包容自己平台的变化呢?
◆ 您可以规划一个上层平台<E&I>来吸纳自己平台的变化
◆ 此平台又称为中间件,其提供稳定的<I>(又称API),也保护自己平台的变动自由度,实现”没钱就改版,改版就有钱”的效果
◆ 中间件还能提供您的专有API,来凸显自己平台的独特性
Sec-10. 讨论:<Android+敏捷>以及落地问题
(可参考网站: http://223.26.63.39/?p=138)
◆ 为什么要将敏捷开发(Agile)带进Android世界呢? 因为Android已经跨越单机开发,迈入多机整合、多屏互动的领域了。Android的项目日益扩大、复杂化。我们需要加入新潮的软件工程、新一代的架构设计思维和模式。
◆ 为什么敏捷开发与Android是个很好的搭配呢? 理由之一是:Android有完善的测试框架,有利于建立TDD测试机制来推动迭代过程。理由之二是:Android平台架构是一个多层框架(Layered Framework)体系,框架内涵是代码,满足敏捷原则:”各项架构设计决策都必须迅速落实为代码”;有利于密切配合敏捷迭代过程,让敏捷方法漂亮地”落地”在Android平台上。
◆ 于是,Android开发团队采用主流的敏捷开发方法,基于创新型的架构设计模式,让项目经理(PM)有效地组织开发、设计及测试人员,灵活敏捷地面对复杂多变的需求,维持高度的用户体验。
~ end ~