Mms模組ConversationList流程分析(1)Mms模組ConversationList流程分析(2)

來源:互聯網
上載者:User

一 代碼位置結構及相關類

..\packages\apps\Mms\src\com\android\mms\ui:存放介面顯示相關的類

..\packages\apps\Mms\src\com\android\mms\data:存放介面顯示需要的資料相關的類

 

主要的類:

ConversationList:資訊對話介面——>ListActivity

ConversationListAdapter:適配器 ——>CursorAdapter

ConversationListItem:對話介面的ListItem View——>RelativeLayout

ConversationListItemData:對話介面列表顯示需要的各項資料

Conversation:顯示所需所有對話資訊的所有資料  

ContactList:每個Thread資訊所對應的連絡人

Contact:一個連絡人資料資訊


二 互動過程:

介面顯示資料擷取過程:

類互動過程:

二 介面資料查詢更新流程圖

三 代碼實現過程分析

1 ConversationList中啟動查詢

onStart(){

         ……

         startAsyncQuery();

}

 

實際上是:

startAsyncQuery() {

         ……

         // mQueryHandler——>ThreadListQueryHandler          ConversationList的內部類

//最終繼承於AsyncQueryHandler

         Conversation.startQueryForAll(mQueryHandler, THREAD_LIST_QUERY_TOKEN);

}       

 

2 Conversation中調用非同步查詢線程

Conversation.startQueryForAll——>

public static void startQueryForAll(AsyncQueryHandler handler, int token) {

                  ……

        final AsyncQueryHandler queryHandler = handler;

        queryHandler.postDelayed(new Runnable() {

                            //匿名內部類

            public void run() {

                     queryHandler.startQuery(

                                        queryToken, null, sAllThreadsUri,

ALL_THREADS_PROJECTION, null, null, Conversations.DEFAULT_SORT_ORDER);

            }

        }, 10);

Conversations.DEFAULT_SORT_ORDER);

}

 

(AsyncQueryHandler使用條用者線程和背景工作執行緒組成)非同步查詢

 

此查詢的是:所有Thread資訊;

 

3 AsyncQueryHandler中查詢過程

 

//各參數的含義

public void startQuery(int token, Object cookie, Uri uri,

            String[] projection, String selection, String[] selectionArgs,

            String orderBy) {

                  //啟動一個工作者線程

mWorkerThreadHandler.sendMessage(msg);

}

——》背景工作執行緒查詢完畢之後,返回到調用者線程;

——》執行AsyncQueryHandler的onQueryComplete函數;

——》 回到自行實現的繼承於AsyncQueryHandler的類中 重寫的onQueryComplete函數中;

——》執行到ThreadListQueryHandler的onQueryComplete函數中;

——》通知到ConversationList,至此查詢Thread資訊的過程結束;

 

資料據查詢就是要使ContentProvider與資料庫進行互動

AsyncQueryHandler的內部類工作者線程WorkerHandler的函數handleMessage中完成;

 

AsyncQueryhandler

A helper class to help make handling asynchronous ContentResolver queries easier.

 

AsyncQueryhandler中有兩個handlerMessage,

一個是基於外部線程looper的,

一個是基於內部WorkerHandler實現的HandlerThread新線程的looper。

外部調用startQuery會通過mWorkerThreadHandler.sendMessage(msg)將查詢發送給

WorkerHandler中處理,即在新線程中查詢,

當WorkerHandler處理完後,把結果發送給AsyncQueryhandler的handlerMessage來調用對應的onXXXComplete函數。

這裡就是把查詢結果返回給原來線程來處理,這就通過兩個handlerMessage實現了兩個線程的訊息互動。

AsyncQueryHandler實現步查詢原理過程在此不作詳細分析;

涉及到線程、HandleMessage

ContentProvider如何與資料庫進行互動在此不作詳細分析;


4 ThreadListQueryHandler

 

         屬於ConversationList類的內部類:繼承於AsyncQueryHandler

重寫抽象函數,接收查詢結果的反饋;

簡單看一下這個函數:

@Override

protected void onQueryComplete(int token, Object cookie, Cursor cursor) {

             switch (token) {

case THREAD_LIST_QUERY_TOKEN:

……

// mListAdapter屬於ConversationListAdapter

mListAdapter.changeCursor(cursor);   //更新UI資料

}

}

——》至此工作將轉移到ConversationListAdapter中進行;

——》產生所需要ViewIten和綁定UI顯示所需要的資料;

 

ConversationListAdapter繼承於CursorAdapter

關於CursorAdapter功能及實現原理作用在此不作詳細分析;

 

5 ConversationListAdapter

 

         繼承於:CursorAdapter;

         簡單看一下:ListView於Adapter以及Cursor的關係:

Adapter的作用就是ListView介面與資料之間的橋樑,

當列表裡的每一項顯示到頁面時,都會調用Adapter的getView方法返回一個View

(對於CursorAdapter具體作用這裡不作詳細分析)


看一下CursorAdapter中的getView函數:

@Override

public View getView(int position, View convertView, ViewGroup parent) {

        ……

        View v;

                   //這裡的作用很關鍵   決定要不要新建立一個ViewItem

        if (convertView == null) {          

                            //建立一個ViewItem

            v = newView(mContext, mCursor, parent);

        } else {

                            //涉及到Recycler機制 保證不會無限去建立Item,重複利用

            v = convertView;    

        }

                   //將資料分配給所要顯示的ViewItem

        bindView(v, mContext, mCursor);

        return v;

}

兩個抽象函數abstract

newView:返回一個View,自訂ViewItem,需要重寫;

bindView:綁定資料,需要重寫;

 

下面看看 ConversationListAdapter對這兩個函數的實現:

newView

@Override

public View newView(Context context, Cursor cursor, ViewGroup parent) {

                   // LayoutInflater擷取res\layout\下的布局檔案xml,並且執行個體化;

                   //這裡就是ListViewItem

        return mFactory.inflate(R.layout.conversation_list_item, parent, false);

}

(具體LayoutInflater的作用在此不詳細分析)

看看conversation_list_item的布局:

<com.android.mms.ui.ConversationListItem xmlns:android="http:.....">

                   //連絡人快捷標識 顯示一張連絡人圖片 點擊彈出相關功能:tellmsg

    <android.widget.QuickContactBadge android:id="@+id/avatar"/>

         //ViewItem可以容納的控制項

    <ImageView android:id="@+id/presence"/>

    <TextView android:id="@+id/from"/>

    <TextView android:id="@+id/date"/>

    <ImageView android:id="@+id/error"/>

    <ImageView android:id="@+id/attachment"/>

    <TextView android:id="@+id/subject"/>

</com.android.mms.ui.ConversationListItem>

 

bindView

       @Override

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

                   //轉化為資訊列表的ListViewItem

        ConversationListItem headerView = (ConversationListItem) view;

                   //使用cursor構建對話資訊 關聯資訊資料和連絡人資料

        Conversation conv = Conversation.from(context, cursor);

                   //構建單個對話資訊資料

        ConversationListItemData ch = new ConversationListItemData(context, conv);

                   //綁定資料

        headerView.bind(context, ch);

    }

 

根據cursor所擷取到的資料個數 迴圈構建;


待續下一篇:Thread中連絡人資料添加

 

Mms模組ConversationList流程分析(2)



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.