求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
Android 4.4 Kitkat Phone工作流程浅析
 
作者 yihongyuelan的博客,火龙果软件    发布于 2014-04-29
 

(一)__概要和学习计划

美国时间 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界面的更新流程。

 
相关文章

手机软件测试用例设计实践
手机客户端UI测试分析
iPhone消息推送机制实现与探讨
Android手机开发(一)
 
相关文档

Android_UI官方设计教程
手机开发平台介绍
android拍照及上传功能
Android讲义智能手机开发
相关课程

Android高级移动应用程序
Android系统开发
Android应用开发
手机软件测试
 
分享到
 
 


android人机界面指南
Android手机开发(一)
Android手机开发(二)
Android手机开发(三)
Android手机开发(四)
iPhone消息推送机制实现探讨
手机软件测试用例设计实践
手机客户端UI测试分析
手机软件自动化测试研究报告
更多...   


Android高级移动应用程序
Android应用开发
Android系统开发
手机软件测试
嵌入式软件测试
Android软、硬、云整合


领先IT公司 android开发平台最佳实践
北京 Android开发技术进阶
某新能源领域企业 Android开发技术
某航天公司 Android、IOS应用软件开发
阿尔卡特 Linux内核驱动
艾默生 嵌入式软件架构设计
西门子 嵌入式架构设计
更多...   
 
 
 
 
 
tml>