下圖爲ComposeMessageActivity中confirmSendMessageIfNeeded部分的信息發送流程。主要以接收者有效性的確認爲主,而後轉向sendMessage方法進行發送。
android
ComposeMessageActivity.sendMessage
從下圖能夠看出,在這個方法中,主要作的事是確認手機狀態的有效性。最終調用WorkingMessage的send方法進行信息的發送。
數據庫
WorkingMessage.send
從下圖能夠看出,在本方法中,對於不一樣類型的消息,分別調用不一樣的方法對其進行處理。並對彩信進行一些簡要的預處理。
短信部分:
WorkingMessage.preSendSmsWorker
以下圖所示,這是短信部分的發送流程。本方法中所涉及到的東西就比較多了。因爲已經轉到了新線程中利用WorkingMessage進行消息的發送,那麼原來ComposeMessage中的那個WorkingMessage就能夠更新了。而後確認一下所屬的會話是否存在,若是不存在就新建一個。
接着,將接收者序列化,調用sendSmsWorker。建立一個SmsMessageSender,將消息存入發送隊列中(type字段設爲6)。通知SmsReceiver發送。
SmsReceiver則調用SmsReceiverService發送隊列中的第一條短信。
在發送以前,還要根據手機卡的不一樣,將短信內容分紅若干塊,保證每塊的大小不超過該卡的限制。在分段後的最後一條短信的sentIntent中,設置EXTRA_MESSAGE_SENT_SEND_NEXT爲true。這樣當短信發送成功後,會調用SmsReceiverService的handleSmsSent方法,發送隊列中的第一條。
而後,對每塊都指定一個sentIntent,當發送出去以後,修改其狀態。若須要報告,還會指定一個deliveryIntent,用於消息報告的處理。這兩個Intent都會被封裝到SmsTracker中,當發送成功後,在SMSDispatcher的handleSendComplete中被取出。sentIntent會被當即執行,將消息狀態轉爲已發送。而deliveryIntent則會被加入deliveryPendingList,等收到消息報告後才被執行(具體代碼在不一樣的dispatcher中)。
發送完畢後,還要對短信上限、消息顯示列表、草稿進行相應的處理。
網絡
SmsReceiverService.handleSmsSent 消息發送後的處理
當sentIntent被執行後,會根據不一樣的結果更新消息的所處信箱。
併發
MessageStatusReceiver 消息報告
當須要接收報告時,會在報告收到以後,在SMSDispatcher中根據不一樣類型手機從deliveryPendingList中取出並執行相應的deliveryIntent。
編碼
SmsReceiverService.handleSmsReceived 接收短信
當RILReceiver有消息收到時,會從RIL向上傳遞,經由SMSDispatcher的dispatchPdus方法生成Intent調用PrivilegedSmsReceiver。
spa
彩信部分:
WorkingMessage.sendMmsWorker
從下圖能夠看出,彩信發送的過程和短信過程有些相似。都須要重置WorkingMessage,獲取實際ThreadId。發送完都要刪除多餘的信息,調用ComposeMessageActivity的onMessageSent。只是彩信沒另外建立一個相似preSendSmsWorker的方法,而是把全部內容都放在sendMmsWorker中處理。同時,刪除草稿的位置也有所不一樣。
線程
TransactionService.onStartCommand
彩信的發送與短信不一樣,是以網絡的方式發送的。
每次調用的時候,先取出全部due_time在當前時間以前的待發送的彩信。而後將它的Uri和transactionType封裝到TransactionBundle中,傳給ServiceHandler。類型設爲EVENT_TRANSACTION_REQUEST。在ServiceHandler中建立一個SendTransaction對象。而後調用processTransaction方法,根據當前Transaction是否已在隊列中,以及當前的鏈接狀態肯定該把這個SendTransaction對象放到哪一個隊列中(mPending爲待發送,mProcessing爲發送中)。同時使用sendMessageDelayed方法發送一個標記爲EVENT_CONTINUE_MMS_CONNECTIVITY的message來保持鏈接。
接着,將TransactionService放入該Transaction對象的觀察者列表,以便於在後面成功發送後,繼續發送待發送的彩信。
接下來,使用SendTransaction的Run方法從數據庫中獲取指定彩信,並構造SendReq,經由HttpUtils發送編碼後的彩信。根據發送結果,選擇是將錯誤狀態存入數據庫,仍是將該彩信轉到已發送箱並通知TransactionService處理待發送的彩信。
對象
TransactionService.update
該方法執行後,先將Transaction從mProcessing列表中移除。若mPending不空,說明有彩信處於已基本處理但未發送狀態,故調用mServiceHandler,設置EVENT_HANDLE_NEXT_PENDING_TRANSACTION進行處理。從mPending隊列中取出第一個,交由processTransaction處理。因爲在以前說過,調用processTransaction的Transaction都會被加入mProcessing隊列,而這個Transaction發送成功後,由會再次通知其觀察者,進而調用TransactionService的update方法繼續發送mPending隊列中的信息。故mPending隊列中的彩信會自動按順序發完。
而後對於成功發送的消息,使用Notification通知用戶(包括消息未讀,消息報告等)。併發送android.intent.action.TRANSACTION_COMPLETED_ACTION的廣播(目前該廣播無人接收,應該是爲了支持應用開發人員而提供的一種廣播)。
隊列
PushReceiver
android的彩信接收應用層部分從PushReceiver開始。當onReceive被調用後,讓屏幕亮5秒,而後建立一個ReceivePushTask並使用它的execute方法。ReceivePushTask是一個AsyncTask,實現了doInBackground方法。當傳入intent後,會在doInBackground中將其中的數據轉成GenericPdu,並根據其消息類型作出不一樣的操做。
若是是發送報告或已讀報告,將其存入數據庫。
若是是彩信通知,若已存在,則不處理。不然將其存入數據庫。啓動TransactionService進行處理。
TransactionService中的處理主要是調用mServiceHandler,大致過程與發送彩信時相同,只是此處建立的是NotificationTransaction。
若是不支持自動下載或數據傳輸沒打開,僅通知mmsc。不然,下載相應彩信,刪除彩信通知,通知mmsc,刪除超過容量限制的彩信,通知TransactionService處理其他待發送的彩信。
圖片