短信接收是從ril.cpp文件經過socket與RIL.java的socket交流,當ril.cpp收到短信後處理完成後會經過socket發送字節流給上層的RIL.java,而在RIL.java中有Receiver架構(該架構主要是一條線程)在不斷監聽, java
Receiver架構代碼: android
class RILReceiver implements Runnable { 網絡
byte[] buffer; 架構
RILReceiver() { app
buffer = new byte[RIL_MAX_COMMAND_BYTES]; socket
} ide
public void 學習
run() { ui
int retryCount = 0; this
try {
for (;;) {
LocalSocket s = null;
LocalSocketAddress l;
try {
s = new LocalSocket();
l = new LocalSocketAddress(SOCKET_NAME_RIL,
LocalSocketAddress.Namespace.RESERVED);
s.connect(l);
} catch (IOException ex) {
try {
if (s != null) {
s.close();
}
} catch (IOException ex2) {
// ignore failure to close after failure to connect
}
// don't print an error message after the the first time
// or after the 8th time
if (retryCount == 8) {
Log.e(LOG_TAG,
"Couldn't find '" + SOCKET_NAME_RIL
+ "' socket after " + retryCount
+ " times, continuing to retry silently");
} else if (retryCount > 0 && retryCount < 8) {
Log.i(LOG_TAG,
"Couldn't find '" + SOCKET_NAME_RIL
+ "' socket; retrying after timeout");
}
try {
Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
} catch (InterruptedException er) {
}
retryCount++;
continue;
}
retryCount = 0;
mSocket = s;
Log.i(LOG_TAG, "Connected to '" + SOCKET_NAME_RIL
+ "' socket");
int length = 0;
try {
InputStream is = mSocket.getInputStream();
for (;;) {
Parcel p;
length = readRilMessage(is, buffer);
if (length < 0) {
// End-of-stream reached
break;
}
p = Parcel.obtain();
p.unmarshall(buffer, 0, length);
p.setDataPosition(0);
// Log.v(LOG_TAG, "Read packet: " + length +
// " bytes");
processResponse(p);
p.recycle();
}
} catch (java.io.IOException ex) {
Log.i(LOG_TAG, "'" + SOCKET_NAME_RIL
+ "' socket closed",
ex);
} catch (Throwable tr) {
Log.e(LOG_TAG, "Uncaught exception read length="
+ length +
"Exception:" + tr.toString());
}
Log.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL
+ "' socket");
setRadioState(RadioState.RADIO_UNAVAILABLE);
try {
mSocket.close();
} catch (IOException ex) {
}
mSocket = null;
RILRequest.resetSerial();
// Clear request list on close
synchronized (mRequestsList) {
for (int i = 0, sz = mRequestsList.size(); i < sz; i++) {
RILRequest rr = mRequestsList.get(i);
rr.onError(RADIO_NOT_AVAILABLE, null);
rr.release();
}
mRequestsList.clear();
}
}
} catch (Throwable tr) {
Log.e(LOG_TAG, "Uncaught exception", tr);
}
}
}
所以從代碼能夠看出獲取到短信消息後通過一系列地分析而後提交給processResponse(p); 方法處理,處理過程當中會有兩種response,一種是主動上報,好比網絡狀態,短信,來電等都不須要通過請求,用unsolicited詞語專門描述,另外一種纔是真正意義上的response,也就是命令的響應用solicited描述。那接收短信就是屬於unsolicited,跳到processUnsolicited (Parcel p)方法,查看該方法可得出會繼續觸發如下方法mSMSRegistrant.notifyRegistrant(new AsyncResult(null, sms, null)); 追溯該方法對象的建立,最後發現該方法設置handler的源頭是在:SMSDispatcher類裏
該類作了一件重要的事:給Command Interface設置handler的處理方法,就是當接收到短信後觸發mSMSRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));方法,而後回調調用以前傳入的handler,接着在handler裏面處理短信消息。
mCm.setOnNewSMS(this, EVENT_NEW_SMS, null);
mCm.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null);
mCm.setOnIccSmsFull(this, EVENT_ICC_FULL, null);
mCm.registerForOn(this, EVENT_RADIO_ON, null);
handler處理接收到的短信消息:
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
switch (msg.what) {
case EVENT_NEW_SMS:
// A new SMS has been received by the device
if (Config.LOGD) {
Log.d(TAG, "New SMS Message Received");
}
SmsMessage sms;
ar = (AsyncResult) msg.obj;
if (ar.exception != null) {
Log.e(TAG, "Exception processing incoming SMS. Exception:"
+ ar.exception);
return;
}
sms = (SmsMessage) ar.result;
try {
int result = dispatchMessage(sms.mWrappedSmsMessage);
if (result != Activity.RESULT_OK) {
// RESULT_OK means that message was broadcast for app(s) to
// handle.
// Any other result, we should ack here.
boolean handled = (result == Intents.RESULT_SMS_HANDLED);
notifyAndAcknowledgeLastIncomingSms(handled, result, null);
}
} catch (RuntimeException ex) {
Log.e(TAG, "Exception dispatching message", ex);
notifyAndAcknowledgeLastIncomingSms(false,
Intents.RESULT_SMS_GENERIC_ERROR, null);
}
break;
}
}
int result = dispatchMessage(sms.mWrappedSmsMessage); 該段會經過子類(GsmSMSDispatcher)的dispatchMessage方法處理。經一系列的判斷處理最後普通短信將交給dispatchPdus(pdus);這個方法處理。
protected void dispatchPdus(byte[][] pdus) {
Intent intent = new Intent(Intents.SMS_RECEIVED_ACTION);
intent.putExtra("pdus", pdus);
dispatch(intent, "android.permission.RECEIVE_SMS");
}
void dispatch(Intent intent, String permission) {
// Hold a wake lock for WAKE_LOCK_TIMEOUT seconds, enough to give any
// receivers time to take their own wake locks.
mWakeLock.acquire(WAKE_LOCK_TIMEOUT);
mContext.sendOrderedBroadcast(intent, permission, mResultReceiver,
this, Activity.RESULT_OK, null, null);
}
最後,咱們能夠看出這個方法將短信經過順序廣播播放出去(action是SMS_RECEIVED_ACTION),不管廣播是否被中斷最後都會調用mResultReceiver,這裏會將已讀或未讀的狀態告訴給對方。若是短信廣播中間沒有受到終止,那麼接下來的流程是:PrivilegedSmsReceiver類接收到android.provider.Telephony.SMS_RECEIVED的請求而後調用 intent.setClass(context, SmsReceiverService.class); 啓動SmsReceiverService服務類來處理短信並保存短信。
本人所轉的博文用於我的學習之用,請支持原創