zoukankan      html  css  js  c++  java
  • Mms模块ConversationList流程分析

    一 代码位置结构及相关类

    ..\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)

  • 相关阅读:
    【转】Fiddler 教程
    【转】java中三个类别加载器的关系以及各自加载的类的范围
    【转】HTTP协议详解
    【转】Google是如何做代码审查的?
    JSP页面的三种include方式
    forward和sendRedirect的差别
    cxf方式实现WebService的简单实例
    Pushlet简单入门实例
    Java学习(二十三):log4j日志打印
    PL/SQL相关问题解决办法汇总
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2432400.html
Copyright © 2011-2022 走看看