在Messaging应用中,编写普通短信SMS和编写彩信MMS的功能是整合在一起的,程序通过特定条件在两种消息类型之间自动转换,转换机制的入口时ComposeMessageActivity.toastConvertInfo()方法。初始创建的信息是SMS类型,当出现以下操作\或者条件成立时,会自动将消息从SMS转化为MMS:
- setSubject:为消息设置主题,通过为Subject编辑框mSubjectTextEditor设置addTextChangedListener而获得回调;
- setAttachment:为消息添加附件(如:图片\视频),通过选项菜单MENU_ADD_ATTACHMENT实现,由showAddAttachmentDialog弹出附件类型列表,并通过addAttachment方法予以响应处理(打开新Activity——SubActivity),然后通过onActivityResult回调方法最终执行到WorkingMessage.setAttachment方法;
- addressContainsEmail:接收地址中包含E-Mail地址,接收者输入框(mRecipientsEditor)有TextChangedListener——mRecipientsWatcher,它在接收者文本内容发生改变时调用mWorkingMessage.setHasEmail()方法以触发消息类型的自动转换机制;
- LengthRequires:消息内容的长度超过SMS标准容量,用于输入消息文本内容的控件时EditText类型的mTextEditor,它有一个TextChangedListener——mTextEditorWatcher,当消息文本内容被输入时会调用到updateCounter()方法,该方法计算了消息长度,并在符合条件时调用mWorkingMessage.setLengthRequiresMms()方法来改变消息类型;
精确捕获具体操作以及条件状态发生变化的关键是——WorkingMessage类,该类代表了正在创建中的消息对象(我们知道ComposeMessageActivity类描绘了创建信息的UI,UI之后的数据对象便是WorkingMessage)它记录着因UI操作而引起的各种状态变化,并将所有变化最终都通过WorkingMessage.update()方法来予以执行实施。
另外一些状态变化被定义在WorkingMessage.MessageStatusListener接口中(注意:当前ComposeMessageActivity是该接口的唯一实现者)包括消息类型发生改变时的回调,以及WorkingMessage对象生命周期阶段的回调:
- onProtocolChanged:消息类型发生改变——即在SMS <----> MMS之间发生变化,该方法在ComposeMessageActivity中的实现是调用了toastConvertInfo(),它显示了Toast提示,通知用户消息类型发生了改变;
- onAttachmentChanged:附件发生变化(反映在WorkingMessage.setAttachment方法)——即在编辑MMS过程中添加/删除(在mAttachmentEditorHandler处理句柄中)附件内容时回调;
- onPreMessageSent:消息发送前,通过runOnUiThread方法在UI线程中调用了resetMessage(),这似乎是个现场清理逻辑,TODO:留待以后仔细学习吧。
- onMessageSent:消息发送前,这并不代表消息发生成功,仅仅是指将消息投递的工作交给了底层网络而已。在ComposeMessageActivity中的实现会重新调用startMsgListQuery()方法,获得当前会话下的消息列表;
- onMaxPendingMessagesReached:当发送队列满载时该方法被回调,在现有的实现中会将当前消息保存为草稿,并给用户一个恰当的提示;
以上就是消息类型的自动转换机制,以及消息状态变化监听器,这样的设计使得我们能够以更简单的方式添加针对WorkingMessage的新功能。