(一)__概要和学习计划
美国时间 2013 年 10 月 31 日, Google 正式发布了全新版本的移动操作系统
Android 4.4 KitKat 。据 google官方介绍,Android 4.4 降低了硬件的需求,提高了程序运行效率。距离
4.4 发布已经过去3个月了,不少朋友也已经体验到了 4.4 所带来的快感,大家可以用过刷入三方ROM(比如知名的CM
ROM等)体验Android 4.4。但从目前来看,基于MTK平台的设备,几乎还没有运行Android
4.4 的设备,OEM厂商拿到系统之后会做许多定制,比如MTK就比高通的定制更多,这也就是为什么国内许多厂商直接拿到MTK的方案就可以出货的原因,当然这也造成了铺货时间更慢。
因工作原因,这里就以MTK平台Android 4.4为例(后文例子代码使用MTK平台
Android 4.4 代码,但基于各方面原因只标注关键代码,以调用时序图为主),整理并记录 Android
4.4 Phone 的工作流程。虽然MTK对于Android的源码定制修改较多,但整体结构还是可以与原生进行对比的。
我们知道通话功能(Telephony)是手机最基本,也是最终要的功能,因此
Google对于这块的改动历来是最少的。在经过了数次迭代之后,我们在 4.4 上发现 Google 对
Phone 模块进行了较大的改动。从图1可以大致看到相关的改动:
原来的Phone应用不见了,取而代之的是Dialer和TeleService,为什么这里把InCallUI单独列出来呢?实际上我们单独去编译InCallUI也是可以生成对应的APK的,但实际上push到手机中却没有效果,因为Dialer的Android.mk中已经将InCallUI的代码包含,也就是已经将InCallUI的代码打包到了Dialer.apk中。如下:
src_dirs := src $(contacts_common_dir)/src $(incallui_dir)/src res_dirs := res $(contacts_common_dir)/res $(incallui_dir)/res LOCAL_SRC_FILES := $(call all-java-files-under, $(src_dirs)) LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dirs)) LOCAL_AAPT_FLAGS := \ --auto-add-overlay \ --extra-packages com.android.contacts.common \ --extra-packages com.android.incallui |
从整体上来讲,也就是说把原来的Phone分成了几块,Dialer现在是拨号应用,TeleService是Server端,InCallUI负责显示。相对于
4.4 之前的Phone应用来说,这样更改后结构更加清晰明了。
(二)__UI结构分析
概述
之前有分析过Android 4.2的InCallScreen结构(传送门),但后面Google发布了Android
4.4即Kitkat,遂决定以之前的文章为模板,重新整理并记录。在4.4中当有来电或去电时,显示给用户的界面如图1,在4.4之前称之为InCallScreen,但在4.4之后叫做InCallActivity。在4.4中我们调出的拨号盘界面,实际为DialtactsActivity并隶属于Dialer应用。4.4
中界面分为3块,CallCardFragment、CallButtonFragment、AnswerFragment,如下所示:
图 1 InCallActivity界面(左:接通
右:来电)
InCallActivity布局分析
在InCallActivity.java中,实现了对界面的初始化,在4.4中界面的布局是通过fragment来完成的,即incall_screen.xml,代码如下:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/main"> <!-- MTK VideoCall fragment --> <FrameLayout android:id="@+id/vtCallFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> <LinearLayout android:id="@+id/in_call_and_button_container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <RelativeLayout android:id="@+id/in_call_card_container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1"> <!-- CallCard fragment 用于显示联系人信息 --> <fragment android:name="com.android.incallui.CallCardFragment" android:id="@+id/callCardFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:layout_alignParentStart="true" /> <!-- 拨号盘 独立出来易于复用 --> <fragment android:name="com.android.incallui.DialpadFragment" android:id="@+id/dialpadFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:layout_alignParentStart="true" /> </RelativeLayout> <!-- 控制按钮 也就是原来的InCallTouchUi --> <fragment android:name="com.android.incallui.CallButtonFragment" android:id="@+id/callButtonFragment" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> <!-- 来电接听/挂断控件 原始使用的系统的GlowpadView --> <fragment android:name="com.android.incallui.AnswerFragment" android:id="@+id/answerFragment" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:gravity="top" android:layout_gravity="bottom|center_horizontal" android:layout_marginBottom="@dimen/glowpadview_margin_bottom" android:visibility="gone" /> <!-- 会议电话管理界面 --> <fragment android:name="com.android.incallui.ConferenceManagerFragment" android:id="@+id/conferenceManagerFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:layout_alignParentStart="true" android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" /> </FrameLayout> |
从整个布局来看,4.4使用fragment代替了原来写死的布局。一方面更能体现出模块化设计,另一方面对于不同屏幕尺寸的适配也更为容易。根据布局文件,InCallActivity主要包括以下几个部分:
1.callCardFragment:用于显示联系人信息及通话时间等;
2.callButtonFragment:通话界面下方的控制按钮,之前叫做InCallTouchUi;
3.conferenceManagerFragment:会议电话的界面;
4.vtCallFragment:视屏通话控件;
5.dialpadFragment:拨号盘显示控件。
6.answerFragment:来电控制控件,用于操作接听/拒接/短信快捷回复。
总的来讲4.4的布局改动不大,取而代之的是使用更加模块化的布局方式。下面主要展示常见的基础布局,包括callCardFragement、callButtonFragment、answerFragment。
callCardFragment通话信息展示
callCardFragment控件,实际上显示的信息主要为通话联系人的相关信息,整个布局显示如下图2:
图 2 callCardFragment界面
callButtonFragment通话控制界面
在4.4中不再称为InCallTouchUi,而是把下方的控制按钮使用fragment包装了起来,相应的布局可以在call_button_fragment.xml中查看。如图3:
图 3 callButtonFragment
answerFragment来电控制界面
这里所说的来电控制界面实际为4.4之前的MultiWaveView,。如图4:
图 4 answerFragment
InCallActivity初始化流程
在InCallActivity的onCreate方法中,完成了各个组件(fragment)的初始化,主要在方法initializeInCall中,代码如下:
private void initializeInCall() { if (mCallButtonFragment == null) { mCallButtonFragment = (CallButtonFragment) getFragmentManager() .findFragmentById(R.id.callButtonFragment); mCallButtonFragment.getView().setVisibility(View.INVISIBLE); } if (mCallCardFragment == null) { mCallCardFragment = (CallCardFragment) getFragmentManager() .findFragmentById(R.id.callCardFragment); } //... ...省略 } |
然后更新了状态栏以及近距离感应器的状态,另外MTK对AOSP多了一些定制加入了一些自己的东西,比如SIMInfoWrapperr就是用于显示保存SIM卡信息用的。相对于4.4之前的代码来说,InCallActivity实际上取代了InCallScreen的功能,初始化流程详细请查看代码。这里得提一下InCallUI中的presenter,它相当于是状态机,保存各种状态,而fragment用于承载显示。
InCallActivity初始化时序图如下:
图 5 InCallActivity初始化时序图
CallButtonFragment控制流程
因为4.4代码的变更,我们主要查看以下几个控件的控制和更新流程:
1.answerFragment:接通/挂断/短信回复时需要使用;
2.dialpadButton:也就是显示或隐藏拨号盘(DTMF);
3.audioButton:开启/关闭扬声器;
4.muteButton:开启/关闭麦克风静音,开启之后对方无法听到你的声音;
5.holdButton:开启/关闭呼叫保持;
6.addButton:增加多路通话;也就是在通话的过程中可以暂停当前通话,拨打另一路通话并接通;
answerFragment滑动控件
answerFragment就是原来的MultiWaveView,现在作为一个独立的fragment存在。控制流程时序图如下:
图 6 anserFragment显示/控制时序图
dialpadButton显示/隐藏拨号盘
dialpadButton点击效果与4.4之前差不多,只是与callCardFragment互斥。
时序图如下:
图 7 接通后显示拨号盘时序图
audioButton开启/关闭扬声器
audioButton用于开启/关闭扬声器,同时在接入线控耳机或者蓝牙耳机后,点击会弹出选项,执行时序图如下:
图 8 开启/关闭扬声器
跟4.4以前的流程相比,现在的控制流程是从InCallUI中的callButtonFragment传递到TeleService中的CallCommandService,并再往下传递。
muteButton开启/关闭麦克风静音
麦克静音的开启/关闭与audioButton类似,执行时序如下:
图 9 麦克风静音开启/关闭
holdButton开启/关闭呼叫保持
holdButton用于呼叫保持开启/关闭,执行时序图如下:
图 10 呼叫保持开启/关闭
addButton添加一路通话
addButton在MTK 4.4的代码中有所改动,显示addButton的条件是:具有物理menu按键或属于"tablet"。
图 11 新增一路通话时序图
endButton挂断当前通话
endButton点击后执行时序图如下:
图 12 挂断当前通话时序图
CallCardFragment通话信息显示
CallCardFragment的更新相对于4.4以前来说,更为独立,代码更为清晰(只不过被MTK这么一改,哎……),整个界面更新时序图如下:
图13 CallCardFragment更新时序图
小结
Android 4.4 Phone在UI上并没有大的改动,但是代码的实现方法却发生了很大的变化,通过分析可以基本理清UI界面的更新流程。
|