SoFunction
Updated on 2025-03-11

Android Mms: Understand Compose in depth

ComposeMessageActivity (hereinafter referred to as Composer) in Mms is the most important component in the entire Mms. It is responsible for editing information, sending information, managing information, receiving information, and interfacing with external applications. There are many classes and components associated with Composer within Mms. Almost all classes and components are associated with Composer. All operational processes about information start with Composer. External Composer is also a public interface that can handle Intent.ACTION_SEND and Intent.ACTION_SENDTO and file types are audio/*, image/*, video/* and text/*.
Composer is a standard activity. Its startup process also needs to go through onCreate(), onStart(), onResume(), and onDestroy(). In addition, other operations must be triggered by the user, or other events, such as new information, database changes, etc.
Initialization process
The initialization process of Composer is to initialize the UI, register some Receiver and Listener, initialize Conversation and WorkingMessage, query information, etc. Among them, initializing Conversation and WorkingMessage is the most important thing, because the UI and some operations depend on whether Conversation exists, as well as the number of messages and whether there are drafts. So here we mainly discuss initializing Conversation and WorkingMessage.
The main process of initialization is carried out in the initialize() function, and the initialize() function is mainly parsed here. The first thing initialize() needs to do is to initialize WorkingMessage and create a new WorkingMessage object mWorkingMessage; then initialize Conversation based on Intent and Bundle. This process is very important because the Conversation object contains all the important data of this session, including whether there are drafts, the number of information, whether it is newly created or existing information, which will affect subsequent initialization work.
initActivityState() mainly depends on two parameters: one is the incoming Bundle and the other is the Intent. It will prioritize viewing of the Bundle. If the Bundle object is not empty, some states will be taken out from the Bundle, such as recipient recipients, exit status exit_on_sent, etc. According to the recipient, you can use the Conversation get() method of Conversation to obtain the Conversation object mConversation, and then mWorkingMessage will read the relevant data from the Bundle. In fact, the initialization from the Bundle is corresponding to onSaveInstanceState(). In onSaveInstanceState(), the recipients will be saved and mWorkingMessage will be written into the Bundle to save the status of the Activity. Generally speaking, onSaveInstanceState saves the state of the Activity, and initActivityState(), the state of the Activity is restored when the Bundle is not empty.
If the Bundle object is empty, then the relevant data will be initialized from the Intent, which is also the logic used in most cases. First, check whether there is thread_id and address in the Intent, and directly search for relevant information about the recipient from the Intent Uri, so as to use () to obtain the Conversation object mConversation. Later, we will try to obtain other information from the Intent, such as the body of the message sms_body, subject subject, etc.
After calling initActivityState(), both mWorkingMessage and mConversation should be correctly initialized. At this time, we have to deal with special Intents: ACTION_SEND and Forward. First, it processes ACTION_SEND, which is an external interface. When an external program wants to send text (text/*), images (image/*), audio (audio/*) and video (video/*) through MMS, it will be sent through Intent.ACTION_SEND. The processing of this Intent is very simple. The Uri of the relevant file is usually placed in (Intent.EXTRA_STREAM) and loading the Uri as an attachment. You can also use Intent.SEND_MULTIPLE to process multiple attachments, but the logic is the same. Forward is when there is forward_message in the Intent, two other options are taken out at the same time, one is the Uri of the information to be forwarded, and the other is the subject and the message body sms_body. Because both SEND and Forward only specify the content of the information and no recipient, the mConversation object has no actual content, and they are the same as the newly created information, but there is the content of the information.
Except for the information of ACTION_SEND and Forward, other information needs to be checked for drafts to load the drafts. Loading a draft is done by (), which checks the status of mConversation and loads it from the database if a draft exists.
At this point, the key initialization operations have been completed and the data has been loaded. The rest is to initialize the UI based on this data, such as whether to display the receiving editing bar, etc.
Destruction process
Composer destruction only needs to do two things. One is to save the currently edited information content, that is, save the draft, if there is any; the other is to save the state through onSaveInstanceState, but this is usually not used, and it will only be called when Composer is killed by the system and hopes to restart.
The work of saving drafts is mainly placed onStop(), so whenever the user leaves the Composer page, he will go to onStop() and check the relevant conditions to determine whether to save the draft. There are three conditions for saving a draft: the information has content ((), content, topic, and attachments), and the information has the correct recipient (it is not available in the database), and the Composer is waiting for other activities (this usually occurs during the process of adding contacts or adding drafts, because it is necessary to jump to other activities, Composer will also go to onStop(), but at this time, because the information is still being edited, you need to save the draft). If the above conditions are not met, the information content will be discarded (()), otherwise the draft will be saved (()).
Interfaces that are disclosed to the public
Like the public interface for component multiplexing in Android, the interface disclosed by Composer is also completed by processing Intents. The main one is Intent.ACTION_SEND, and the other is Intent.ACTION_SENDTO. The declaration of the interface is the IntentFilter in the AndroidManifest file. For processing, there are two places. One is that in initActivityState(), the address, sms_body and subject will be tried to remove from the Intent; in addition, for ACTION_SEND, handleSendIntent() needs to be processed clearly, because the content that needs to retrieve information from the Intent is usually a multimedia file, and the multimedia file is taken out and then added as an attachment to the information through ().
There is another interface for sharing contacts. The way to share contacts is to send the contact information as the content of the text message. This process is actually processed first by ShareContactsViaSMS in Contacts. It will read the contact information from the database, then spell it into a string and use Intent to pass it to Mms as sms_body.
Interaction with other components
Composer needs to constantly interact with other components during the editing process of information, especially during the editing of MMS, such as adding pictures, adding audio, adding videos or taking pictures, shooting videos, etc. For selecting pictures, selecting videos is to interact with the Gallery application and send the GET_CONTENT Intent to the Gallery. The Gallery will list the pictures and videos for users to choose. After the user selects, the Gallery will pass the Uri of the picture or video selected by the user to Composer, and then the Composer will use the passed Uir to add attachments. For audio, it interacts with the Music application, and the logic is similar. The process for taking pictures and recording videos and recording audio is slightly different. Take pictures and take videos. The path to output in the request Intent is specified by Intent.EXTRA_OUTPUT to specify the output Uri. During the shooting process, Camera will write the data in the specified Uri, and then Composer will read the file directly from this Uri (difficult to 2.3, 2.3 means Camera puts the Uri of the file in the Intent). TempFileProvider is specially used to manage temporary storage of data when shooting pictures and videos. The Uri passed to Camera is "content://mms_temp_file/scrapSpace". This Uri is managed by TempFileProvider and used by Camera. When Camera wants to openFile() when openingFile() is required, TempFileProvider will create a temporary file. On the external memory card, /sdcard/Android/data//mms_temp_file/scrapSpace/. The pictures and videos taken by Camera are stored in this file. There are also methods in TempFileProvider to operate this file. For example, () is to rename the . file into a .3gp video. In addition to Composer, this TempFileProvider is used, and this temporary file is also used when editing a slide in SlideEditorActivity, because when editing a slide, you can also add videos of pictures through Camera.