Android Mms之:深入理解Compose
Mms中的ComposeMessageActivity(以下簡稱Composer)是整個Mms中最重要的一個組件,它負(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是一個標(biāo)準(zhǔn)的Activity,它的啟動流程也要經(jīng)過onCreate(), onStart(),onResume(),銷毀流程要經(jīng)過onPause(),onStop()和onDestroy() 。除此之外,其他的操作都要經(jīng)過用戶來觸發(fā),或者由其他事件,比如新來信息,數(shù)據(jù)庫變化等。
初始化流程
Composer的初始化流程要做的事情有初始化UI,注冊一些Receiver和Listener,初始化Conversation和WorkingMessage,查詢信息等。其中,初始始化Conversation和WorkingMessage是最重要的,因為UI和一些操作要依賴于Conversation是否存在,以及消息數(shù)量和是否有草稿。所以這里我們主要討論初始化Conversation和WorkingMessage。
初始化的主要流程都是在initialize()函數(shù)中進(jìn)行的,這里也主要解析下initialize()函數(shù)。initialize()最先要做的就是初始化WorkingMessage,創(chuàng)建一個新的WorkingMessage對象mWorkingMessage;然后就是根據(jù)Intent和Bundle來初始化Conversation,這一過程相當(dāng)重要,因為Conversation對象含有這一會話的所有重要數(shù)據(jù),包括是否有草稿,信息的數(shù)量,是新建的信息還是已有信息,這些信息都將影響后續(xù)的初始化工作。
initActivityState()主要看二個參數(shù)一個是所傳入的Bundle另一個就是Intent。它會優(yōu)先查看Bundle,如果Bundle對象不為空的話,會從Bundle之中取出一些狀態(tài),比如收信人recipients,比如退出狀態(tài)exit_on_sent等。根據(jù)所拿出來的的收信人就可以用Conversation的get()方法來獲取Conversation對象mConversation,之后便會讓mWorkingMessage從Bundle中讀取相關(guān)的數(shù)據(jù)。其實,這里從Bundle中初始化是與onSaveInstanceState()相對應(yīng)的,在onSaveInstanceState()中會保存recipients和讓mWorkingMessage寫數(shù)據(jù)到Bundle中,以保存Activity的狀態(tài)??傮w來講,onSaveInstanceState是保存Activity的狀態(tài),而initActivityState()中當(dāng)Bundle不為空時是恢復(fù)Activity的狀態(tài)。
如果Bundle對象為空的話,那么就從Intent中來初始化相關(guān)的數(shù)據(jù),這也是大多數(shù)的情況所走的邏輯。首先是檢查Intent中是否有thread_id和address,也直接從Intent的Uri中搜尋收信人的相關(guān)信息,以便用Conversation.get()來獲取Conversation對象mConversation。之后還會試圖從Intent中獲取其他信息比如消息的主體sms_body,主題subject等。
調(diào)用完initActivityState()以后,mWorkingMessage和mConversation二個對象應(yīng)該都被正確的初始化了。這時候就要處理特殊的Intent:ACTION_SEND和Forward了。先是處理ACTION_SEND,這是對外的接口,當(dāng)外部程序想通過MMS來發(fā)送文本(text/*),圖片(image/*),音頻(audio/*)和視頻(video/*)時就會通過Intent.ACTION_SEND來發(fā)送。對于這個Intent的處理很簡單就是把相關(guān)文件的Uri,通常放在intent.getExtras(Intent.EXTRA_STREAM)中,把Uri加載為附件,也可以通過Intent.SEND_MULTIPLE來處理多個附件,但是邏輯是一樣的。Forward是Intent當(dāng)中有forward_message時,同時取出另外二個選項,一個是要轉(zhuǎn)發(fā)的信息的Uri,一個是主題subject和消息主體sms_body。因為對于SEND和Forward都僅指定信息的內(nèi)容而沒有指定收信人,所以mConversation對象是沒有實際內(nèi)容的,它們都會與新建信息是一樣的,只不過有信息的內(nèi)容。
除了ACTION_SEND和Forward的信息有內(nèi)容外,其他的信息都需要檢查是否有草稿,以便能加載草稿。加載草稿是由mWorkingMessage.loadDraft()來完成的,它會檢查mConversation的狀態(tài),如果有草稿存在就從數(shù)據(jù)庫中加載出來。
到此,初始化的關(guān)鍵操作都已完成,數(shù)據(jù)的加載都已完成,剩下的工作就是根據(jù)這些數(shù)據(jù)來初始化UI,比如是否顯示收信編輯欄等。
銷毀流程
Composer的銷毀要做的只有二件事,一個是保存當(dāng)前編輯的信息內(nèi)容,也就是保存草稿,如果有的話;另一個就是通過onSaveInstanceState來保存狀態(tài),不過這個通常用不到,只有當(dāng)Composer被系統(tǒng)殺掉并希望重啟時才會調(diào)用到。
保存草稿的工作主要放在onStop()的時候,所以每當(dāng)用戶離開Composer頁面都會走進(jìn)onStop()也就都會檢查相關(guān)的條件以確定是否要保存草稿。保存草稿的條件有三個:信息有內(nèi)容(mWorkingMessage.isWorthSaving(),有內(nèi)容,有主題,有附件均可),并且信息有正確的收信人(在不在數(shù)據(jù)庫中均可),還有就是Composer在等待其他Activity(這個通常出現(xiàn)在添加聯(lián)系人或添加草稿過程中,因為要跳轉(zhuǎn)到其他Activity,所以Composer也會走到onStop(),但是這個時候因為信息還在編輯中,所以就需要保存草稿)。如果以上條件不滿足就丟棄信息內(nèi)容(mWorkingMessage.discard()),否則就保存草稿(mWorkingMessage.saveDraft())。
對外公開的接口
跟Android中組件復(fù)用的公開接口一樣,Composer對外公開的接口也是通過處理Intent來完成的,主要是二個Intent一個是Intent.ACTION_SEND,另一個就是Intent.ACTION_SENDTO。接口的聲明處是在AndroidManifest文件中的IntentFilter。對于處理,有二個地方,一個是在initActivityState()中,會從Intent中嘗試取出address, sms_body 和subject;另外對于ACTION_SEND需要明顯的處理handleSendIntent(),因為需要從Intent中取出信息的內(nèi)容通常都是多媒體文件,取出多媒體文件然后通過mWorkingMessage.setAttachment()添加為信息的附件。
還有一個接口就是對于分享聯(lián)系人,分享聯(lián)系人的方式是把聯(lián)系人的信息作為短信的內(nèi)容發(fā)送出去。這個過程實際上是由Contacts中的ShareContactsViaSMS來先行處理,它會把聯(lián)系人的信息從數(shù)據(jù)庫中讀取出來,然后拼成一個字串再用Intent當(dāng)成sms_body傳給Mms發(fā)送。
與其他組件的交互
Composer在編輯信息過程中,特別是編輯MMS的過程中需要不斷的與其他組件進(jìn)行交互,比如添加圖片,添加音頻,添加視頻或拍攝圖片,拍攝視頻等。對于選擇圖片,選擇視頻來講是通過與Gallery應(yīng)用進(jìn)行交互,發(fā)送GET_CONTENT的Intent給Gallery,Gallery會列出圖片和視頻供用戶選擇,當(dāng)用戶選擇后,Gallery會把用戶所選擇的圖片或視頻的Uri傳給Composer,之后Composer就用傳過來的Uir進(jìn)行添加附件的動作。對于音頻是與Music應(yīng)用進(jìn)行交互,邏輯類似。對于拍攝圖片和拍攝視頻和錄制音頻流程稍有不同。拍攝圖片和拍攝視頻在請求Intent中要指定輸出的路徑通過Intent.EXTRA_OUTPUT來指定輸出Uri。Camera在拍攝的過程中會把數(shù)據(jù)寫在所指定的Uri中,之后Composer會直接從這個Uri中讀取文件(這里與2.3不同,2.3是Camera把文件的Uri放在Intent中)。TempFileProvider就專門用于管理拍攝圖片和拍攝視頻時臨時存儲數(shù)據(jù)的。傳給Camera的Uri是”content://mms_temp_file/scrapSpace”,這個Uri由TempFileProvider來管理,由Camera來使用,當(dāng)Camera要寫數(shù)據(jù)時openFile()時,TempFileProvider就會創(chuàng)建一個臨時文件,在外部存儲卡上/sdcard/Android/data/com.android.mms/mms_temp_file/scrapSpace/.temp.jpg,Camera所拍攝的圖片和視頻都存放在這個文件之中。TempFileProvider中還有方法以操作這個文件,比如TempFileProvider.renaceScrapFile()就是把.temp.jpg文件重命名成為一個.3gp的視頻。除了Composer會用到這個TempFileProvider,在SlideEditorActivity中編輯一張幻燈片的時候也會用到這個臨時文件,因為編輯幻燈片的時候也是能夠通過Camera來添加圖片的視頻的。
- Android Compose自定義TextField實現(xiàn)自定義的輸入框
- Android Jetpack Compose實現(xiàn)列表吸頂效果
- Android Jetpack Compose無限加載列表
- Android之Compose頁面切換動畫介紹
- Android Compose實現(xiàn)底部按鈕以及首頁內(nèi)容詳細(xì)過程
- Android Compose實現(xiàn)伸縮ToolBar的思路詳解
- Android?Jetpack庫剖析之ViewModel組件篇
- Android?Jetpack庫剖析之LiveData組件篇
- Android?Jetpack結(jié)構(gòu)運用Compose實現(xiàn)微博長按點贊彩虹效果
相關(guān)文章
Android開發(fā)歡迎頁點擊跳過倒計時進(jìn)入主頁
沒點擊跳過自然進(jìn)入主頁,點擊跳過之后立即進(jìn)入主頁,這個功能怎么實現(xiàn)呢,本文通過實例代碼給大家介紹Android開發(fā)歡迎頁點擊跳過倒計時進(jìn)入主頁,感興趣的朋友一起看看吧2023-12-12Android仿新浪微博發(fā)送菜單界面的實現(xiàn)
這篇文章主要介紹了Android仿新浪微博發(fā)送菜單界面的實現(xiàn),幫助大家更好的理解和學(xué)習(xí)使用Android開發(fā),感興趣的朋友可以了解下2021-04-04Android應(yīng)用啟動流程之從啟動到可交互的過程解析
這篇文章將給大家總結(jié)學(xué)習(xí)Android 基礎(chǔ)知識,Android應(yīng)用啟動流程,從啟動到可交互的過程解析,在學(xué)習(xí)過程中,大家最好是把源碼下載下來,感興趣的小伙伴跟著小編一起來看看吧2023-08-08在啟動欄制作android studio啟動圖標(biāo)
這篇文章主要介紹了在啟動欄制作android studio啟動圖標(biāo)的相關(guān)知識,需要的朋友可以參考下2018-03-03Android應(yīng)用UI開發(fā)中Fragment的常見用法小結(jié)
這篇文章主要介紹了Android應(yīng)用UI開發(fā)中Fragment的常見用法小結(jié),Fragment的存在是為了解決不同屏幕分辯率的動態(tài)和靈活UI設(shè)計,需要的朋友可以參考下2016-02-02Android中NavigationView的使用與相關(guān)問題解決
大家都知道NavigationView的引入讓 Android側(cè)邊欄實現(xiàn)起來相當(dāng)方便,最近公司項目中也使用這個新的控件完成了側(cè)邊欄的改版。在使用過程中遇到一些問題所以記錄一下。本文分為兩個部分,一是基本使用,二是相關(guān)問題的解決,感興趣的朋友們下面來一起看看吧。2016-10-10淺談Android手機聯(lián)系人開發(fā)之增刪查改功能
這篇文章主要介紹了Android手機聯(lián)系人開發(fā)之增刪查改功能,需要的朋友可以參考下2017-05-05Android基于OpenCV實現(xiàn)圖像修復(fù)
實際應(yīng)用中,圖像常常容易受損,如存在污漬的鏡頭、舊照片的劃痕、人為的涂畫(比如馬賽克),亦或是圖像本身的損壞。修復(fù)圖像就成為一個常見的需求了,本文講述Android基于OpenCV實現(xiàn)圖像修復(fù)的步驟,有此需求的朋友可以參考下2021-06-06Android實現(xiàn)圖片點擊預(yù)覽效果(zoom動畫)
本文主要介紹了Android實現(xiàn)圖片點擊預(yù)覽效果的方法步驟。具有很好的參考價值,下面跟著小編一起來看下吧2017-03-03