作为Dialer Owner,作一下基于M版本的总结吧。
在线源码阅读:http://androidxref.com
总体轮廓
手机之所以被称为手机,是因为它是一个通讯工具,而完成这一核心功能的软件模块,即为Telephony。
Telephony包含的范围非常广泛,单拿上层来说,大致可以划分成五大部分:Telephony应用(Dialer
、Contacts
、Mms
),service Telephony和service Telecomm,framework Telephony和framework Telecomm。
现在这一架构的主要变化是从L版本开始的,相较旧版的主要变迁可以参考:Android 4.4 Kitkat Phone工作流程浅析(十二)__4.4小结与5.0概览
图片资料
本文只关注Dialer,那么先看几张Nexus 6p的实机截图来个感性的认识:
架构分析
Dialer主要涉及的包有:
1)/packages/apps下
Dialer
,InCallUI
,ContactsCommon
,PhoneCommon
,VoiceDialer
凭借makefile,分包可以非常的自由随意,看如下片断:
6incallui_dir := ../InCallUI
7contacts_common_dir := ../ContactsCommon
8phone_common_dir := ../PhoneCommon
9
10src_dirs := src \
11 $(incallui_dir)/src \
12 $(contacts_common_dir)/src \
13 $(phone_common_dir)/src
Dialer
,InCallUI
,PhoneCommon
,ContactsCommon
全都在src_dirs路径下了,于是最终的Dialer.apk由这四个包下的代码编译生成。
VoiceDialer
提供语音相关功能,入口看下图:
但是,此功能侵略性过强,在天朝是基本残废的,在海外多数运营商也不喜欢表示要去除,所以不予关注。
2)/packages/services下
Mms
,Telephony
,Telecomm
,生成MmsService.apk,Telecom.apk与TeleService.apk,对Dialer来说是提供通话菜单功能的。
应该说不管从逻辑还是物理上,切分出来都是大有好处,这样才能让Android能够良好支持第三方通讯类应用。
3)/packages/providers下
TelephonyProvider
,ContactsProvider
,数据创建及查询,当然也是要切分的部分。
4)frameworks/opt和frameworks/base下
telephony
等和上面类似的眼熟名字,具体关系到各种功能点如MmiCode,Clear Code,Number match,Number format,DTMF,FDN等等等等。
具体分析
看完整体架构之后,单单一个Dialer包的定位也变得很清晰了:它就只是一个拨号器而已。
1.层次结构
Dialer的UI是否美观是个见仁见智的问题,我个人还是挺喜欢的。
这里我们只谈其实现原理。
这是Dialer的主layout dialtacts_activity.xml
:
16<FrameLayout
17 xmlns:android="http://schemas.android.com/apk/res/android"
18 android:id="@+id/dialtacts_mainlayout"
19 android:layout_width="match_parent"
20 android:layout_height="match_parent"
21 android:orientation="vertical"
22 android:focusable="true"
23 android:focusableInTouchMode="true"
24 android:clipChildren="false"
25 android:background="@color/background_dialer_light">
26
27 <FrameLayout
28 android:id="@+id/dialtacts_container"
29 android:layout_width="match_parent"
30 android:layout_height="match_parent"
31 android:clipChildren="false">
32 <!-- The main contacts grid -->
33 <FrameLayout
34 android:layout_height="match_parent"
35 android:layout_width="match_parent"
36 android:id="@+id/dialtacts_frame"
37 android:clipChildren="false" />
38 </FrameLayout>
39
40 <FrameLayout
41 android:id="@+id/floating_action_button_container"
42