欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android Mms之:深入理解Compose

 更新時(shí)間:2013年05月22日 10:25:26   作者:  
本篇文章是對(duì)Compose進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下

Mms中的ComposeMessageActivity(以下簡(jiǎn)稱Composer)是整個(gè)Mms中最重要的一個(gè)組件,它負(fù)責(zé)編輯信息,發(fā)送信息,管理信息,接收信息,與外部應(yīng)用接口。在Mms內(nèi)部與Composer關(guān)聯(lián)的類和組件特別多,幾乎所有的類和組件都與Composer有關(guān)聯(lián),關(guān)于信息的所有操作流程都起始于Composer;在外部Composer也是公開的接口,能夠處理Intent.ACTION_SEND和Intent.ACTION_SENDTO以及文件類型為audio/*,image/*,video/*和text/*。
Composer是一個(gè)標(biāo)準(zhǔn)的Activity,它的啟動(dòng)流程也要經(jīng)過(guò)onCreate(), onStart(),onResume(),銷毀流程要經(jīng)過(guò)onPause(),onStop()和onDestroy() 。除此之外,其他的操作都要經(jīng)過(guò)用戶來(lái)觸發(fā),或者由其他事件,比如新來(lái)信息,數(shù)據(jù)庫(kù)變化等。
初始化流程
Composer的初始化流程要做的事情有初始化UI,注冊(cè)一些Receiver和Listener,初始化Conversation和WorkingMessage,查詢信息等。其中,初始始化Conversation和WorkingMessage是最重要的,因?yàn)閁I和一些操作要依賴于Conversation是否存在,以及消息數(shù)量和是否有草稿。所以這里我們主要討論初始化Conversation和WorkingMessage。
初始化的主要流程都是在initialize()函數(shù)中進(jìn)行的,這里也主要解析下initialize()函數(shù)。initialize()最先要做的就是初始化WorkingMessage,創(chuàng)建一個(gè)新的WorkingMessage對(duì)象mWorkingMessage;然后就是根據(jù)Intent和Bundle來(lái)初始化Conversation,這一過(guò)程相當(dāng)重要,因?yàn)镃onversation對(duì)象含有這一會(huì)話的所有重要數(shù)據(jù),包括是否有草稿,信息的數(shù)量,是新建的信息還是已有信息,這些信息都將影響后續(xù)的初始化工作。
initActivityState()主要看二個(gè)參數(shù)一個(gè)是所傳入的Bundle另一個(gè)就是Intent。它會(huì)優(yōu)先查看Bundle,如果Bundle對(duì)象不為空的話,會(huì)從Bundle之中取出一些狀態(tài),比如收信人recipients,比如退出狀態(tài)exit_on_sent等。根據(jù)所拿出來(lái)的的收信人就可以用Conversation的get()方法來(lái)獲取Conversation對(duì)象mConversation,之后便會(huì)讓mWorkingMessage從Bundle中讀取相關(guān)的數(shù)據(jù)。其實(shí),這里從Bundle中初始化是與onSaveInstanceState()相對(duì)應(yīng)的,在onSaveInstanceState()中會(huì)保存recipients和讓mWorkingMessage寫數(shù)據(jù)到Bundle中,以保存Activity的狀態(tài)??傮w來(lái)講,onSaveInstanceState是保存Activity的狀態(tài),而initActivityState()中當(dāng)Bundle不為空時(shí)是恢復(fù)Activity的狀態(tài)。
如果Bundle對(duì)象為空的話,那么就從Intent中來(lái)初始化相關(guān)的數(shù)據(jù),這也是大多數(shù)的情況所走的邏輯。首先是檢查Intent中是否有thread_id和address,也直接從Intent的Uri中搜尋收信人的相關(guān)信息,以便用Conversation.get()來(lái)獲取Conversation對(duì)象mConversation。之后還會(huì)試圖從Intent中獲取其他信息比如消息的主體sms_body,主題subject等。
調(diào)用完initActivityState()以后,mWorkingMessage和mConversation二個(gè)對(duì)象應(yīng)該都被正確的初始化了。這時(shí)候就要處理特殊的Intent:ACTION_SEND和Forward了。先是處理ACTION_SEND,這是對(duì)外的接口,當(dāng)外部程序想通過(guò)MMS來(lái)發(fā)送文本(text/*),圖片(image/*),音頻(audio/*)和視頻(video/*)時(shí)就會(huì)通過(guò)Intent.ACTION_SEND來(lái)發(fā)送。對(duì)于這個(gè)Intent的處理很簡(jiǎn)單就是把相關(guān)文件的Uri,通常放在intent.getExtras(Intent.EXTRA_STREAM)中,把Uri加載為附件,也可以通過(guò)Intent.SEND_MULTIPLE來(lái)處理多個(gè)附件,但是邏輯是一樣的。Forward是Intent當(dāng)中有forward_message時(shí),同時(shí)取出另外二個(gè)選項(xiàng),一個(gè)是要轉(zhuǎn)發(fā)的信息的Uri,一個(gè)是主題subject和消息主體sms_body。因?yàn)閷?duì)于SEND和Forward都僅指定信息的內(nèi)容而沒(méi)有指定收信人,所以mConversation對(duì)象是沒(méi)有實(shí)際內(nèi)容的,它們都會(huì)與新建信息是一樣的,只不過(guò)有信息的內(nèi)容。
除了ACTION_SEND和Forward的信息有內(nèi)容外,其他的信息都需要檢查是否有草稿,以便能加載草稿。加載草稿是由mWorkingMessage.loadDraft()來(lái)完成的,它會(huì)檢查mConversation的狀態(tài),如果有草稿存在就從數(shù)據(jù)庫(kù)中加載出來(lái)。
到此,初始化的關(guān)鍵操作都已完成,數(shù)據(jù)的加載都已完成,剩下的工作就是根據(jù)這些數(shù)據(jù)來(lái)初始化UI,比如是否顯示收信編輯欄等。
銷毀流程
Composer的銷毀要做的只有二件事,一個(gè)是保存當(dāng)前編輯的信息內(nèi)容,也就是保存草稿,如果有的話;另一個(gè)就是通過(guò)onSaveInstanceState來(lái)保存狀態(tài),不過(guò)這個(gè)通常用不到,只有當(dāng)Composer被系統(tǒng)殺掉并希望重啟時(shí)才會(huì)調(diào)用到。
保存草稿的工作主要放在onStop()的時(shí)候,所以每當(dāng)用戶離開Composer頁(yè)面都會(huì)走進(jìn)onStop()也就都會(huì)檢查相關(guān)的條件以確定是否要保存草稿。保存草稿的條件有三個(gè):信息有內(nèi)容(mWorkingMessage.isWorthSaving(),有內(nèi)容,有主題,有附件均可),并且信息有正確的收信人(在不在數(shù)據(jù)庫(kù)中均可),還有就是Composer在等待其他Activity(這個(gè)通常出現(xiàn)在添加聯(lián)系人或添加草稿過(guò)程中,因?yàn)橐D(zhuǎn)到其他Activity,所以Composer也會(huì)走到onStop(),但是這個(gè)時(shí)候因?yàn)樾畔⑦€在編輯中,所以就需要保存草稿)。如果以上條件不滿足就丟棄信息內(nèi)容(mWorkingMessage.discard()),否則就保存草稿(mWorkingMessage.saveDraft())。
對(duì)外公開的接口
跟Android中組件復(fù)用的公開接口一樣,Composer對(duì)外公開的接口也是通過(guò)處理Intent來(lái)完成的,主要是二個(gè)Intent一個(gè)是Intent.ACTION_SEND,另一個(gè)就是Intent.ACTION_SENDTO。接口的聲明處是在AndroidManifest文件中的IntentFilter。對(duì)于處理,有二個(gè)地方,一個(gè)是在initActivityState()中,會(huì)從Intent中嘗試取出address, sms_body 和subject;另外對(duì)于ACTION_SEND需要明顯的處理handleSendIntent(),因?yàn)樾枰獜腎ntent中取出信息的內(nèi)容通常都是多媒體文件,取出多媒體文件然后通過(guò)mWorkingMessage.setAttachment()添加為信息的附件。
還有一個(gè)接口就是對(duì)于分享聯(lián)系人,分享聯(lián)系人的方式是把聯(lián)系人的信息作為短信的內(nèi)容發(fā)送出去。這個(gè)過(guò)程實(shí)際上是由Contacts中的ShareContactsViaSMS來(lái)先行處理,它會(huì)把聯(lián)系人的信息從數(shù)據(jù)庫(kù)中讀取出來(lái),然后拼成一個(gè)字串再用Intent當(dāng)成sms_body傳給Mms發(fā)送。
與其他組件的交互
Composer在編輯信息過(guò)程中,特別是編輯MMS的過(guò)程中需要不斷的與其他組件進(jìn)行交互,比如添加圖片,添加音頻,添加視頻或拍攝圖片,拍攝視頻等。對(duì)于選擇圖片,選擇視頻來(lái)講是通過(guò)與Gallery應(yīng)用進(jìn)行交互,發(fā)送GET_CONTENT的Intent給Gallery,Gallery會(huì)列出圖片和視頻供用戶選擇,當(dāng)用戶選擇后,Gallery會(huì)把用戶所選擇的圖片或視頻的Uri傳給Composer,之后Composer就用傳過(guò)來(lái)的Uir進(jìn)行添加附件的動(dòng)作。對(duì)于音頻是與Music應(yīng)用進(jìn)行交互,邏輯類似。對(duì)于拍攝圖片和拍攝視頻和錄制音頻流程稍有不同。拍攝圖片和拍攝視頻在請(qǐng)求Intent中要指定輸出的路徑通過(guò)Intent.EXTRA_OUTPUT來(lái)指定輸出Uri。Camera在拍攝的過(guò)程中會(huì)把數(shù)據(jù)寫在所指定的Uri中,之后Composer會(huì)直接從這個(gè)Uri中讀取文件(這里與2.3不同,2.3是Camera把文件的Uri放在Intent中)。TempFileProvider就專門用于管理拍攝圖片和拍攝視頻時(shí)臨時(shí)存儲(chǔ)數(shù)據(jù)的。傳給Camera的Uri是”content://mms_temp_file/scrapSpace”,這個(gè)Uri由TempFileProvider來(lái)管理,由Camera來(lái)使用,當(dāng)Camera要寫數(shù)據(jù)時(shí)openFile()時(shí),TempFileProvider就會(huì)創(chuàng)建一個(gè)臨時(shí)文件,在外部存儲(chǔ)卡上/sdcard/Android/data/com.android.mms/mms_temp_file/scrapSpace/.temp.jpg,Camera所拍攝的圖片和視頻都存放在這個(gè)文件之中。TempFileProvider中還有方法以操作這個(gè)文件,比如TempFileProvider.renaceScrapFile()就是把.temp.jpg文件重命名成為一個(gè).3gp的視頻。除了Composer會(huì)用到這個(gè)TempFileProvider,在SlideEditorActivity中編輯一張幻燈片的時(shí)候也會(huì)用到這個(gè)臨時(shí)文件,因?yàn)榫庉嫽脽羝臅r(shí)候也是能夠通過(guò)Camera來(lái)添加圖片的視頻的。

相關(guān)文章

最新評(píng)論