四、接收短信流程分析
接收短信时数据流向跟踪
1.最早是Modem接收到新短信,将新短信发送给RIL层。(RIL层未看)
2.在RIL.processUnsolicited()中处理接收到的短信消息。
如果接收到的是RIL_UNSOL_RESPONSE_NEW_SMS消息,说明是GSM短信,调用SmsMessage.newFromCMT()建立gsm.SmsMessage对象。并通过mGsmSmsRegistrant对象发出短信状态报告的消息通知。
如果接收到的是RIL_UNSOL_RESPONSE_CDMA_NEW_SMS消息,说明是CDMA短信,调用SmsMessage.newFromParcel()建立cdma.SmsMessage对象。并通过mCdmaSmsRegistrant对象发出短信状态报告的消息通知。(下面的流程按GSM短信分析)
3.RIL对象是在SMSDispatcher的构造方法中获取到的。而在其子类GSMSMSDispatcher的构造方法中对RIL对象做了如下操作:
mCm.setOnNewGsmSms(this, EVENT_NEW_SMS, null);
该方法完成了mGsmSmsRegistrant对象的消息注册。
因此,RIL通过mGsmSmsRegistrant对象发出的EVENT_NEW_SMS消息通知,会在GSMSMSDispatcher的handleMessage中接收,提取出SmsMessage对象,并将它的成员变量SmsMessageBase对象交给dispatchMessage方法处理 。该方法出现分支:data download message和 normal message,普通短信交给 dispatchNormalMessage方法处理。
4.SmsMessageBase对象被传递到SMSDispatcher.dispatchNormalMessage()内时,该方法有以下逻辑处理:
如果该短信是WAP短信,那么调用dispatchWapPdu
如果该短信是port addressed短信,那么调用dispatchPortAddressedPdus
如果该短信是partial短信,那么调用processMessagePart
如果该短信是normal短信,那么调用dispatchPdus方法,传入的参数为SmsMessageBase对象的pdu数据
5.在SMSDispatcher.dispatchPdus方法中,创建了SMS_RECEIVED_ACTION类型的Intent对象,并存入pdu数据和format。该方法继续调用SMSDispatcher.dispatch(),并传入Intent对象。在SMSDispatcher.dispatch()中,取得wake lock点亮屏幕,并发出接收到新短信的广播。
6.Application层的PrivilegedSmsReceiver类的onReceive方法接收到该广播,该方法会调用onReceiveWithPrivilege方法来启动SmsReceiverService服务。
7.SmsReceiverService的handleMessage方法接收到SMS_RECEIVED_ACTION消息,并交给handleSmsReceived方法来处理接收到的Intent对象。该方法有以下两步处理:
首先,调用SMS.Intents.getMessagesFromIntent方法(首先(byte[])intent.getSerializableExtra("pdus")得到pdu,然后msgs[i] = SmsMessage.createFromPdu(pdus[i], format)得到SmsMessage)
然后,通过insertMessage()将新短信保存到SMS.inbox中。
最后,提示有新短信到达。