看彩信代码差不多有一个多月了,觉得有必要做下笔记,我看的是1.5cupcake的代码,也大致浏览了一下2.2froyo的,差别不大。看代码的时候最好结合一些WAP协议来看,比如WAP-206-MMSCTR-20020115-a,WAP-209-MMSEncapsulation-20020105-a,另外还可以看一下SMIL手册及其 MMS 应用指南(Series 60 Developer Platform 2.0)
一、收发彩信宏观上四个步骤
a、终端A向彩信中心(MMSC)发送一条彩信,通过WAP网关POST到MMSC
b、MMSC通过PushProxy网关,向SMSC发送PUSH消息,SMSC转发到终端B
c、终端B通过WAP网关利用GET方法从MMSC获取一条彩信
d、MMSC通过PushProxy网关和SMSC向终端A发送一条传送报告(delivery report)
二、MMS和外部模块的交互
MMS主要跟Telephony框架和http,前者用于接收push消息,后者用来进行数据传输
三、MMS的模块划分
a、Model,管理彩信元素(文字,图片,音频/视频)的布局,资源URI,用户事件的响应等
b、DOM、对SMIL文件的抽象,描述SMIL文件节点和事件的触发
c、UI,短信/彩信的浏览,编辑等
d、Transaction,彩信的传输
e、provider.Telephony 彩信的存储
此外,org.w3c.dom包是对数据模型的更高的抽象,com.google.android.mms是对彩信pdu和data base的封装
四、各模块的类图
csdn的日志的贴图功能很不给力,所以只能少量的描述一下
a、Model DOM
TxetModel,ImageModel...等都是Model的子类,实现EventListener.handleEvent(Event evt)接口,这个接口很重要,是用来响应用户动作的,而DOM的类都是继承自NodeImpl,NodeImpl有EventListener的聚合,也就是说DOM会调用到handleEvent,这样就将model和dom两个模块联系起来了
b、Transaction
Observer.java: void update(Observable observable);
Observable.java: public void notifyObservers() 会调用update()方法
Transaction.java: public abstract void process(); 它的子类主要重写该方法
ReadRecTransaction.java只是单纯的发送阅读报告,不需要从彩信中心返回结果,因此不需要继承Runnable接口。
RetrieveTransaction和NotificationTransaction功能都是获取彩信,前者用于手动获取,后者用于自动获取。
五、动态图
本来在永中work上好了图,无奈这里上传不了,还是作罢。
a、彩信的接收
ril层会主动上报RIL_UNSOL_RESPONSE_NEW_SMS消息,Telephony框架层的SMSDispatcher.java将push消息继续向上分发,应用层的PushReceiver.java收到Intent.WAP_PUSH_RECEIVED_ACTION,然后调用PduParser将字节数据解析成pdu(M-Notification.ind
),PDU分HEADER和BODY,而BODY又多个PART组成,然后,调用PduPersister类将pdu存入数据库,再启动TransactionService,
在TransactionService里面,根据传输的类型(Transaction.NOTIFICATION_TRANSACTION),创建NotificationTransaction实例,该实例发送GET请求,获取到新的PDU(M-retrieve.conf),替代刚才的pdu存入到数据库里面,发送传送报告(M-NotifyResp.ind)
b、彩信的发送
MmsMessageSender.java首先调用PduPersister.load(mMessageUri)形成PDU,启动TransactionSrvice,创建SendTransaction实例,该实例通过HTTP把pdu(M-Send.req)POST出去,返回一个发送确认的pdu(M-Send.conf),然后讲M-Send.req从Outbox移到Sent,一段时间后,PushReceiver将收到一个传送报告的pdu(M-Delivery.ind)