Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android Mms之:深入理解Compose

Android Mms之:深入理解Compose

編輯:關於Android編程

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來添加圖片的視頻的。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved