Android Mms專題之:Compose詳解

來源:互聯網
上載者:User

Mms中的ComposeMessageActivity(以下簡稱Composer)是整個Mms中最重要的一個組件,它負責編輯資訊,發送資訊,管理資訊,接收資訊,與外部應用介面。在Mms內部與Composer關聯的類和組件特別多,幾乎所有的類和組件都與Composer有關聯,關於資訊的所有操作流程都起始於Composer;在外部Composer也是公開的介面,能夠處理Intent.ACTION_SEND和Intent.ACTION_SENDTO以及檔案類型為audio/*,image/*,video/*和text/*。
Composer是一個標準的Activity,它的啟動流程也要經過onCreate(), onStart(),onResume(),銷毀流程要經過onPause(),onStop()和onDestroy() 。除此之外,其他的操作都要經過使用者來觸發,或者由其他事件,比如新來資訊,資料庫變化等。

初始化流程

Composer的初始化流程要做的事情有初始化UI,註冊一些Receiver和Listener,初始化Conversation和WorkingMessage,查詢資訊等。其中,初始始化Conversation和WorkingMessage是最重要的,因為UI和一些操作要依賴於Conversation是否存在,以及訊息數量和是否有草稿。所以這裡我們主要討論初始化Conversation和WorkingMessage。
初始化的主要流程都是在initialize()函數中進行的,這裡也主要解析下initialize()函數。initialize()最先要做的就是初始化WorkingMessage,建立一個新的WorkingMessage對象mWorkingMessage;然後就是根據Intent和Bundle來初始化Conversation,這一過程相當重要,因為Conversation對象含有這一會話的所有重要資料,包括是否有草稿,資訊的數量,是建立的資訊還是已有資訊,這些資訊都將影響後續的初始化工作。
initActivityState()主要看二個參數一個是所傳入的Bundle另一個就是Intent。它會優先查看Bundle,如果Bundle對象不為空白的話,會從Bundle之中取出一些狀態,比如收信人recipients,比如退出狀態exit_on_sent等。根據所拿出來的的收信人就可以用Conversation的get()方法來擷取Conversation對象mConversation,之後便會讓mWorkingMessage從Bundle中讀取相關的資料。其實,這裡從Bundle中初始化是與onSaveInstanceState()相對應的,在onSaveInstanceState()中會儲存recipients和讓mWorkingMessage寫資料到Bundle中,以儲存Activity的狀態。總體來講,onSaveInstanceState是儲存Activity的狀態,而initActivityState()中當Bundle不為空白時是恢複Activity的狀態。
如果Bundle對象為空白的話,那麼就從Intent中來初始化相關的資料,這也是大多數的情況所走的邏輯。首先是檢查Intent中是否有thread_id和address,也直接從Intent的Uri中搜尋收信人的相關資訊,以便用Conversation.get()來擷取Conversation對象mConversation。之後還會試圖從Intent中擷取其他資訊比如訊息的主體sms_body,主題subject等。
調用完initActivityState()以後,mWorkingMessage和mConversation二個對象應該都被正確的初始化了。這時候就要處理特殊的Intent:ACTION_SEND和Forward了。先是處理ACTION_SEND,這是對外的介面,當外部程式想通過MMS來發送文本(text/*),圖片(image/*),音頻(audio/*)和視頻(video/*)時就會通過Intent.ACTION_SEND來發送。對於這個Intent的處理很簡單就是把相關檔案的Uri,通常放在intent.getExtras(Intent.EXTRA_STREAM)中,把Uri載入為附件,也可以通過Intent.SEND_MULTIPLE來處理多個附件,但是邏輯是一樣的。Forward是Intent當中有forward_message時,同時取出另外二個選項,一個是要轉寄的資訊的Uri,一個是主題subject和訊息主體sms_body。因為對於SEND和Forward都僅指定資訊的內容而沒有指定收信人,所以mConversation對象是沒有實際內容的,它們都會與建立資訊是一樣的,只不過有資訊的內容。
除了ACTION_SEND和Forward的資訊有內容外,其他的資訊都需要檢查是否有草稿,以便能載入草稿。載入草稿是由mWorkingMessage.loadDraft()來完成的,它會檢查mConversation的狀態,如果有草稿存在就從資料庫中載入出來。
到此,初始化的關鍵操作都已完成,資料的載入都已完成,剩下的工作就是根據這些資料來初始化UI,比如是否顯示收信編輯欄等。

銷毀流程

Composer的銷毀要做的只有二件事,一個是儲存當前編輯的資訊內容,也就是儲存草稿,如果有的話;另一個就是通過onSaveInstanceState來儲存狀態,不過這個通常用不到,只有當Composer被系統殺掉並希望重啟時才會調用到。
儲存草稿的工作主要放在onStop()的時候,所以每當使用者離開Composer頁面都會走進onStop()也就都會檢查相關的條件以確定是否要儲存草稿。儲存草稿的條件有三個:資訊有內容(mWorkingMessage.isWorthSaving(),有內容,有主題,有附件均可),並且資訊有正確的收信人(在不在資料庫中均可),還有就是Composer在等待其他Activity(這個通常出現在新增連絡人...或添加草稿過程中,因為要跳轉到其他Activity,所以Composer也會走到onStop(),但是這個時候因為資訊還在編輯中,所以就需要儲存草稿)。如果以上條件不滿足就丟棄資訊內容(mWorkingMessage.discard()),否則就儲存草稿(mWorkingMessage.saveDraft())。

對外公開的介面

跟Android中組件複用的公開介面一樣,Composer對外公開的介面也是通過處理Intent來完成的,主要是二個Intent一個是Intent.ACTION_SEND,另一個就是Intent.ACTION_SENDTO。介面的聲明處是在AndroidManifest檔案中的IntentFilter。對於處理,有二個地方,一個是在initActivityState()中,會從Intent中嘗試取出address, sms_body 和subject;另外對於ACTION_SEND需要明顯的處理handleSendIntent(),因為需要從Intent中取出資訊的內容通常都是多媒體檔案,取出多媒體檔案然後通過mWorkingMessage.setAttachment()添加為資訊的附件。
還有一個介面就是對於分享連絡人,分享連絡人的方式是把連絡人的資訊作為簡訊的內容發送出去。這個過程實際上是由Contacts中的ShareContactsViaSMS來先行處理,它會把連絡人的資訊從資料庫中讀取出來,然後拼成一個字串再用Intent當成sms_body傳給Mms發送。

與其他組件的互動

Composer在編輯資訊過程中,特別是編輯MMS的過程中需要不斷的與其他組件進行互動,比如添加圖片,添加音頻,添加視頻或拍攝圖片,拍攝視頻等。對於選擇圖片,選擇視頻來講是通過與Gallery應用進行互動,發送GET_CONTENT的Intent給Gallery,Gallery會列出圖片和視頻供使用者選擇,當使用者選擇後,Gallery會把使用者所選擇的圖片或視頻的Uri傳給Composer,之後Composer就用傳過來的Uir進行添加附件的動作。對於音頻是與Music應用進行互動,邏輯類似。對於拍攝圖片和拍攝視頻和錄製音頻流程稍有不同。拍攝圖片和拍攝視頻在請求Intent中要指定輸出的路徑通過Intent.EXTRA_OUTPUT來指定輸出Uri。Camera在拍攝的過程中會把資料寫在所指定的Uri中,之後Composer會直接從這個Uri中讀取檔案(這裡與2.3不同,2.3是Camera把檔案的Uri放在Intent中)。TempFileProvider就專門用於管理拍攝圖片和拍攝視頻時臨時儲存資料的。傳給Camera的Uri是”content://mms_temp_file/scrapSpace”,這個Uri由TempFileProvider來管理,由Camera來使用,當Camera要寫資料時openFile()時,TempFileProvider就會建立一個臨時檔案,在外部儲存卡上/sdcard/Android/data/com.android.mms/mms_temp_file/scrapSpace/.temp.jpg,Camera所拍攝的圖片和視頻都存放在這個檔案之中。TempFileProvider中還有方法以操作這個檔案,比如TempFileProvider.renaceScrapFile()就是把.temp.jpg檔案重新命名成為一個.3gp的視頻。除了Composer會用到這個TempFileProvider,在SlideEditorActivity中編輯一張投影片的時候也會用到這個臨時檔案,因為編輯投影片的時候也是能夠通過Camera來添加圖片的視頻的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.