闲散整理,带你走进Android短信源码

过年在家无聊,发现以前写的短信App分析文章,以及ppt,想着就整理出来。好了,废话不多说,开使正文


简介

这是Google的Mms源码,不过在15年中旬就停止维护了,后期的维护交给了各大开发商。

事实上,市场上的大多短信应用都是基于Google原生改的

这里是我fork的工程地址 ps:加了注释的

这里是谷歌工程地址

其实Mms很复杂的,谷歌官方的是简单功能的短信,不过就基础功能版本的短信也够撸了,比如一个彩信附件的显示,其继承关系图就足够复杂,而且彩信还是是smil语言,还有什么pdb,够人好好看一番。

我们可以通过这个工程,看到谷歌人员是怎么写代码的,当然由于这个app的版本迭代很多了,没有重构,没有采用Google推荐的MVP模式。

更别提Rx那些了,这个工程就是4大组件开干。

初识架构

Mms模块构成图

由于懒,简答说,整个短信主要是由2个主要Activity,加2个远程Service,2个本地Service,4个Provider以及4个Receiver组成。其他的一些小功能的就不说了。

  • 所谓2个主要Activity,一为短信联系人界面,即一个listView,外加一些增删功能,另一个为短信编辑界面
  • 所谓2个远程Service,即为AIDL且进程号不同,跑在系统中的负责短信发送接收,彩信发送接收的服务
  • 所谓2个本地Service,即为本应用后台负责发送短信与彩信的服务,实为调用系统服务发送接收,不过本地有部分逻辑需要处理。
  • 4个Provider,为:SuggestionsProvider,用于搜索建议,与Search配合,

    SmsProvider 管理短信数据表

    MmsProvider 管理彩信数据库

    MmsSmsProvider 管理短彩信共同数据库
  • 4个Receiver,为:SmsReceiver 短信到来
    PushReceiver 推送,Class0
    SmsSystemEventReceiver 系统启动
    PrivilegedSmsReceiver 彩信接收

基础知识

我们来梳理一下基础概念,一些重要的对象。

Thread对话---是指用户与某个联系人或某几个联系人之间的一系列信息交互。在Mms中,用Thread Id来标识和管理对话,Thread Id也即在数据库表threads中的_id。可能用Conversation是更易于理解。但是Thread本身就有对话的意思,某些论坛中的一个帖子在英语里就叫Thread。Thread的词典释义是:”因特网上关于一个题目一连串的信息 (计算机用语)”,所以这里用Thread,也是比较恰当的。

Conversation--是用来管理Thread对话的,Conversation是一个Thread对话的抽象出来数据结构,它能够,从数据 库中查询,删除一个对话中的消息等,每一个Conversation有一个唯一的Thread Id。但是它也负责一些所有对话的管理,比如查询所有的对话,删除所有的对话等(这个应该是设计上面的问题)。
事实上,Conversation更多时候是充当前前对话的角色,比如在新新建信息时,编辑信息时,或是查看某个对话时,都会有一个 Conversation对象存在在,以代表当前信息所处的对话。它是一个近似单键,都是通过Conversation的静态方法来获得 Conversation对象,有一些其他的方法也是静态的。

ConversationList--负责显示和编辑所有的对话,以列表形式显示所有的Thread,每一项代表一个Thread,通常也会显示这个Thread的状态,如有无草稿,信息发送/接收是否成功等。

Message--消息,泛指短信SMS和彩信MMS。因为不再区分短信和彩信,在对话列表,草稿管理和信息列表中它们都是一样的,都是信息。 Message的数据结构是MessageItem,它是一个纯数据结构,里面存储着关于一个信息的所有数据,还有MessageListitem,它是 一个View,专门用于在消息列表中显示一个信息,里面的数据都是从MessageItem获取。它们统一都被 ComposeMessageActivity,MessageListAdapter和MessageListView来管理。

WorkingMessage--当前消息,它是专门用于代表当前正在创建和编辑的信息的数据结构无论是短信还是彩信,在创建和编辑的时候都放在一个WorkingMessage对象里面。这个对象也负责信息的发送,存储和存储为草稿。

Slideshow--在Mms应用里面,彩信是以Slideshow幻灯片的形式来展示的。一个彩信可以有多张幻灯片,每张幻灯片上面可以有图 片,文字,音频和视频,可以设置每张幻灯片的浏览时长,布局等,这里的幻灯片与Office中的PowerPoint有几分类似。幻灯片的数目限制是以彩 信允许的附件大小为上限,这个也与每张幻灯片上面的媒体大小有关。可以这样讲MMS就是以幻灯片形式存在的,创建的时候是一张幻灯片一张幻灯片的编辑,收 到的彩信或编辑完后,就可以一张张的放映浏览幻灯片。
需要注意的是以幻灯片方式显示彩信仅是应用程序层的处理方式,不同的信息应用程序会以不同的方式处理彩信,实际的彩信的数据是以标准的Pdu方式进行发送和接收,是应用程序在发送前把幻灯片转化成为Pdu,并在接收后把Pdu转化成为自己可识别的幻灯片。

Recipient接受人,这里是指信息的接收者,要么是一个陌生的电话号码,要么是一个陌生的电子邮件地址(彩信时),要么就是手机联系人数据库 中的联系人。彩信和短信对接收人的数量都有限制,这个也是在Mms的Settings时面可以更改的。每一条信息要想发送成功,必须保证接收人是一个合法 的联系人,合法也是不同的手机有不同的定义,但通常来讲,要么与联系人数据库中的某个联系人匹配,要么是一个电话号码,要么是一个电子邮件地址,其他情况 则视为不合法,对于有不合法接收人的信息,不会进行发送。管理联系人的数据结构是Contact和ContactList,其中ContactList是 一个以Contact为元素的ArrayList。Contact不但存储有联系人的一些信息,如名字,电话号码等,它还能与联系人数据库进行同步,也就 是它能保证它是一个合法的联络人,并在数据库中存在。在信息发送前会先进行一次联系人同步,以保证已有的联系人是正确的。


UI初窥

短信AppUI

以下分析大致分为:

  • UI分析
  • 短信发送、接收
  • 彩信
  • 数据库

UI主要组成

  • 我们看会话列表数据刷新图


    会话列表刷新
  • 编辑界面的类图
编辑界面类图

短信发送、接收

  • 短信发送流程图
短信发送流程图
  • 短信发送类图
短信发送类图
  • 短信接收流程图
短信接收流程图

彩信

MMS为Multimedia Messaging Service的缩写,中文译为多媒体短信服务,通过网络来传输数据

MMS发送和接收: 手机终端合成多媒体消息后,可以向网内的所有合法用户发送多媒体消息。不直接投递给接收方。先发送给一个中间服务器 (MMSC)。彩信网关暂时保存彩信,然后通过Push 协议给接收方发送一个Push 通知,接收方收到通知后再从MMSC 上获取彩信内容。

与MMSC交互的数据为PDU数据

Google内置包里为我们提供了一系列操作PDU的类(com.google.android.mms)

  • PduPersister 用于管理PDU存储
  • PduParser 用于解析PDU
  • PduComposer 用于生成PDU
彩信发送流程图
彩信接收流程图
彩信类图

彩信不自动下载的情况

在会话界面的MessageListItem中会显示一个download按钮,当用户点击该按钮

-->mContext.startService(intent);

-->TransactionService中,处理Action为 RETRIEVE_TRANSACTION的请求

--> transaction = new RetrieveTransaction();

-->transaction.process();

-->byte[] resp = getPdu(mContentLocation);

-->PduParser解析数据成pdu

-->isDuplicateMessage 判断是否是重复的短信

-->PduPersister 再将其存储

-->sendAcknowledgeInd(retrieveConf); 再发送Ack给MMSC

-->notifyObservers(); 通知service ,状态改变

Mms数据库,在短信应用程序中占有很重要的地位

1.负责数据的存储 短信,彩信,对话列表都存储在数据库中

2.负责大量的通信 先待发短信存储到数据库中,发送服务将待短信从数据库取出

3.通过ContentProvider,间接的肩负起通知界面数据刷新工作 getContext().getContentResolver().notifyChange() 通知观察者去刷新数据

threads表:在ConversationList.Java中显示的当前短信

sms表:短信内容

pdu表: 彩信内容

part表:(存储彩信内容(文本、音乐、图象)文件名

pending_msgs:存储待发送的短信与彩信

drm:用于彩信权限管理

words:用于存储关键字,搜索时用

SmsProvider用于短信相关数据的存取 MmsProvider用于彩信相关数据的存取

MmsSmsProvider则用于短彩信通用数据的存取,如会话信息、接收者、草稿(公共属性)等


谢谢大家阅读,如有帮助,来个喜欢或者关注吧!


本文作者:Anderson/Jerey_Jobs

博客地址 : 夏敏的博客/Anderson大码渣/Jerey_Jobs

简书地址 : Anderson大码渣

CSDN地址 : Jerey_Jobs的专栏

github地址 : Jerey_Jobs

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容