Android Call 功能在各个frameworks层中的结构整理 (四)

终于到了CallManager.java。我对它的理解是,,这个类是frameworks层在Call业务中面对App层的最后一层封装。通过这个类,我们可以对底层的业务做进一步归纳,实际上也是为PhoneApp提供了Call业务的控制接口(CallManagerclass provides an abstract layer forPhoneApp to access and control calls.)。那么,CallManager都有哪些功用,参考该类的说明文档我们可以得知:

1.对诸如dial()和hangup()等业务的操作

2.一些通道的使能操作,比如说CanConference()

3.消息的注册

由此,对CallManager的几个功能我做了划分如下:

这里举出的方法只占其中的一部分。

在进行下一步分析之前,先要理清一个概念,CalManager所维护的几个泛型数组里放置的,究竟是什么?

从CallManager的构造函数可以看到,CallManager实例化后最重要的就是如下几个数组对象:

privateCallManager() {mPhones= new ArrayList<Phone>();mRingingCalls= new ArrayList<Call>();mBackgroundCalls = new ArrayList<Call>();mForegroundCalls = new ArrayList<Call>();mDefaultPhone = null;}

回忆一下在CallTracker和Call类讨论时所归纳的结论,当时抽象出来的三种实例变量ringingCall,forgroundCall和backgroundCall在这里终于得以派上用场。对于应用层而言,frameworks层将Call业务的抽象即可用这三种Call实例及其引申出的状态来形容。

Call.state与抽象出的三种不同的Call实例,有如下一一对应关系,画的比较粗糙~

当然,这里并不是说Call.state的几种状态就完全被CallManager.java封装了,在某些情况下,为了精确获取当前Call实例的状态,app层仍然会直接调用Call.state来进行比对。但是一般来说,通过CallManager.java进一步抽象封装后的Call实例更能说明当前维护的通话状态。用一种比较通俗的方法来说,上层所关注的不过就是这么三种情况下的通话:

前台通话(正在拨出以及已经接通了的电话,注意是作为主叫方)

后台电话(前台已经有了一通电话,而被挂起在后台的电话)

响铃电话(正在响铃而尚未被接通的电话,包括存在前台通话时的情况,注意是作为被叫方)

不过有一点需要修正的是,在之前的文章里我认为IDLE、DISCONNECTED、DISCONNECTING这三种状态可以不用考虑。今天又看了一下接口注释,实际上这三种状态对于ringingCall,forgroundCall和backgroundCall也的确没有任何影响——因为处于IDLE、DISCONNECTED状态下时,三种Call实例状态都认为是有效的。而DISCONNECTING确实是不予考虑。

从下图可以看出,针对如上的三种通话状态,有派生出与之相关的Call,Connection以及Phone的状态

一一进行分析:

1.getXXCall& hasXXCall

这部分的方法比较多,稍微整理一下,剔除私有方法可以看到,公共方法中与ForegroundCall,BackgroundCall和RingingCall三种状态相关的,大致上可以分为两类。一类是判断当前Call是否为对应状态下的通话(has),另一种为获取处于对应状态下通话实例(get)。那么对于后者,有人会问,getForegroundCall()与getActiveFgCall()有什么区别,从代码中可以看出,getForegroundCall()通过unmodifiableList方法返回一个前台通话列表,可以用来轮询当前所有的前台通话,而getActiveFgCall()则返回一个具体的前台通话实例。

此外,需要注意的是,由于后台通话可能有多个(比如说多方通话尚未合并时),此时调用getFirstActiveBgCall()获取的是第一通后台电话,同理对于getFirstActiveRingingCall()。

2.getXXPhone

再看对应于ForegroundCall,BackgroundCall和RingingCall三种状态下的getFgPhone,getBgPhone和getRingingPhone,都是取自于Call.getPhone()方法获取对应对象的。追根结底,它们仍然获取的是对应CallTracker维护的Phone实例,这里就不细说了。

值得一提的是私有方法getPhoneBase(),该方法用来消掉代理,指向真正所用到的Phone对象,在需要真正Phone对象作为参数的场合会用到。

3.getXXConnection

对应的方法会返回一个前台/后台状态下的通话链路列表,通过轮询该列表可以拿到当前处于该状态下的所有Connections。

需要注意的是getFgCallLatestConnection(),该方法用来返回最新的一次前台通话Connection,用到的场合一般是需要最新一次前台通话链路的地方,比如说“重拨电话”的时候。

洋洋洒洒说了这么多,其实对于fremework层Call业务而言,我的理解是,掌握其中各个通路状态以及抽象出来的实例含义更为重要,倒是对于其中的四大业务dial,hangupCall,rejectCall以及acceptCall的流程掌握,反倒是水到渠成的事情。

版权声明:本文为博主原创文章,未经博主允许不得转载。

好好的管教你自己,不要管别人。

Android Call 功能在各个frameworks层中的结构整理 (四)

相关文章:

你感兴趣的文章:

标签云: