Mms module ConversationList Process Analysis (2) Mms module ConversationList Process Analysis (1)

Source: Internet
Author: User

Followed by the previous article:Mms module ConversationList Process Analysis (1)


Query of three contact data

The previously obtained cursor obtained using AsyncQueryHandler only queries all the conversation information data. However, the contact only saves its ID: recipientIds;

You also need to obtain the contact information based on this recipientIds; this is obtained when packaging information data for ListItem;

Conversation conv = Conversation. from (context, cursor );Obtain contact information;

Let's take a look at this process:

First, from the Cache in Conversation, find whether the Thread information corresponding to the current cursor already exists in the Cache,

If yes, update it and return it; otherwise, it is created and added to the Cache;

Public static Conversation from (Context context, Cursor cursor ){

Long threadId = cursor. getLong (ID );

If (threadId> 0 ){

//SlaveConversationSearch in cacheCursorCorrespondingThreadInformation

Conversation conv = Cache. get (threadId );

If (conv! = Null ){

 

//Cache already existsUpdate the existing conv in-place

FillFromCursor (context, conv, cursor, false );

Return conv;

}

}

//It does not exist in the cache and is newly created

Conversation conv = new Conversation (context, cursor, false );

Cache. put (conv );

Return conv;

}

In fact, functions are used for both update and creation.FillFromCursor ();

Let's take a look at what this function has done;

Private static void fillFromCursor (Context context, Conversation conv,

Cursor c, boolean allowQuery ){

Synchronized(Conv ){

//EnterConvBasic instance dialog information For exampleThreadId,Date,Count,Attach,TypeAnd so on;

}

 

//ObtainCursorContactIds;

String recipientIds = c. getString (RECIPIENT_IDS );

//PassRecipientIdsObtain the corresponding contact data:Address,Name......

ContactListRecipients = ContactList.GetByIds(RecipientIds, allowQuery );

 

Synchronized(Conv ){

//Associate contact data

Conv. mRecipients = recipients;

//Calculate the number of unread messages

}

}

(Note the following:SynchronizedThis is thread-related, which is not analyzed in detail here)

-- ContactList.GetByIds

Here, I will go to the ContactList class to perform operations (). Here is the class in the mms data package;

 

1 ContactList

The query process is as follows:

The following sections detail the flowchart;

ContactList

This class is inherited from ArrayList: public class ContactList extendsArrayList <Contact>{}

Public static ContactListGetByIds(String spaceSepIds, boolean canBlock ){

ContactList list = new ContactList ();

// ForeachStatement

For (RecipientIdCache. Entry entry Entry:RecipientIdCache

. GetAddresses (spaceSepIds )){//AccordingIdGet number Access Database

If (entry! = Null &&! TextUtils. isEmpty (entry. number )){

//Obtain contact data by phone number

Contact contact = Contact. get (entry. number, canBlock );

Contact. setRecipientId (entry. id );

List. add (contact );

}

}

//Back to contact list ToConversation;

Return list;

}

 

Contact contact = Contact. get (entry. number, canBlock) here; pass in the number

-- "Is transferred to the Contact for execution;

Let's take a look at the get method of this class.

 

2 ContactObtain contact data asynchronously or in blocking mode

Number:Contact number

CanBlock:Will determine whether to obtain contact data in a blocking or asynchronous manner

Public static ContactGet(String number, boolean canBlock ){

//YesContactsCacheClass instanceGetMethod

Return sContactCache. get (number, canBlock );

}

 

Next let's take a look.ContactsCacheInsideGetMethod

ContactsCacheYesContactClass internal class;

Public ContactGet(String number, boolean canBlock ){

// Return a contact. No matter whether the database exists or not, search for matching numbers from the internal cache.

// If it does not exist, it is returned directly. If it does not exist, a new one is returned.

Contact contact =Get(Number); // internal search

Runnable r = null;

Synchronized(Contact ){

While (canBlock & contact. mQueryPending) {// whether to block

Contact. wait ();}

Final Contact c = contact; // anonymous internal class implementation thread

R= New Runnable (){

Public voidRun(){

// You still need to update the contact data in the thread, regardless of whether the data is obtained from the cache or not.

UpdateContact(C );}

};}

If (canBlock ){

R. run (); // blocking method

} Else {

PushTask (r); // Asynchronous Method}

Return contact;

}

 

This method is used to obtain the contact data asynchronously or in blocking mode. Use thisGetThe contact data obtained by the method may only contain numbers, but not other data information;

 

Next let's take a look.UpdateContactMethod

Private voidUpdateContact(Final Contact c ){

Contact entry = getContactInfo (c. mNumber );

 

// Obtain Contact data from the database

Contact entry = getContactInfo (c. mNumber );

// Set the data information of Contact instance c: name id ......

 

// Configure y to update who?

// Who? Here It isConversationListItem;

UpdateListener l; // obtain a Listener object from the UpdateListener queue of the Contact.

// Update the Contact data used by the listener

L. onUpdate (c)

}

3 ContactMediumUpdateListenerAdd

There isUpdateListenerThe object isConversationListItemInstance: When will it be passed in?

When the bind method is calledBindView;

Public final void bind (){

......

Contact.AddListener(This); // Add UpdateListener

}

 

4Contact Handling Method

ContactThere are two ways to process contact data: asynchronous and blocking. Here we will not make a detailed analysis;

 

So here is a point that I don't understand!

1) loading the contact data corresponding to a Thread ListItem may be executed cyclically in the ContactList getByIds method;

2) asynchronous processing of the contact data corresponding to each number

3) add pushTask (r) To TaskStack and give up control of CPU;

4)TaskStackMiddle threadMWorkerThread; there are many uncertainties in asynchronous execution;

5) One asynchronous executionUpdateContactThe ItemList will be notified to update the data. Why not update the ItemList after processing all the numbers in the Thread information;

In this case, when joining TaskStack, execute:

Public voidPush(Runnable r ){

Synchronized(MThingsToLoad ){

MThingsToLoad. add (r );

MThingsToLoad. Y (); // discard resource control

}

}Wait hereGetByIdsAdd all numbersTaskStackTo process;

However, every time the thread run method is updated, the UI is updated when a contact is updated. In this way, do not waste time and resources;

ThisMWorkerThreadThe thread is started when MmsApp is started.

MmsApp. java

@ Override

Public void onCreate (){

......

// Create a ContactsCache object and a TaskStack object

// TaskStack is the internal class of ContactsCache. Its constructor starts the thread.

Contact. init (this );

}

 

ThisMmsThis contact management is complicated! What we know here may be correct and will be improved later.

 

 

5. Update data to the interface

Return to the bindView function of ConversationListAdapter.

@ Override

Public void bindView (View view, Context context, Cursor cursor ){

ConversationListItem headerView = (ConversationListItem) view;

Conversation conv = Conversation.From(Context, cursor );

ConversationListItemData ch = new ConversationListItemData (context, conv );

HeaderView.Bind(Context, ch );

}

 

You need to take a look at the bind function executed by headerView. bind:

//UpdateListViewItemControls

Void bind (Context context, final ConversationListItemData ch ){

......

// Date

MDateView. setText (ch. getDate ());

// From.

MFromView. setText (formatMessage (ch ));

//Register for updates in changes of any of the contacts in this conversation.

ContactList contacts = ch. getContacts ();

Contact. addListener (this );//YesOnUpdateFunction

// Subject

MSubjectView. setText (ch. getSubject ());

// Avatar

UpdateAvatarView ();

}

 

This is the main process from the entire ConversationList interface to data loading.

 

Here is only a framework for analyzing and introducing each module;

Further detailed analysis is required for each module.

Some of them may be incorrect. Please correct them;

Or you will make corrections and updates later.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.