public final void unbind() {
   if (Log.isLoggable(LogTag.CONTACT, Log.DEBUG)) {
     Log.v(TAG, "unbind: contacts.removeListeners " + this);
   }
   // Unregister contact update callbacks.
   Contact.removeListener(this);
 }
  private void updateAvatarView() {
    Drawable avatarDrawable;
    if (mConversation.getRecipients().size() == 1) {

      Contact contact = mConversation.getRecipients().get(0);

      // to be continued
      avatarDrawable = contact.getAvatar(mContext, sDefaultContactImage);

      if (contact.existsInDatabase()) { // 010查看联系人是否存在于通讯录
        mAvatarView.assignContactUri(contact.getUri());
      } else {
        mAvatarView.assignContactFromPhone(contact.getNumber(), true);
      }
    } else {
      // TODO get a multiple recipients asset (or do something else)
      avatarDrawable = sDefaultContactImage;
      mAvatarView.assignContactUri(null);
    }
    mAvatarView.setImageDrawable(avatarDrawable);
    mAvatarView.setVisibility(View.VISIBLE);
  }
  public final void bind(Context context, final Conversation conversation) {
    // if (DEBUG) Log.v(TAG, "bind()");

    mConversation = conversation;

    updateBackground();

    LayoutParams attachmentLayout = (LayoutParams) mAttachmentView.getLayoutParams();
    boolean hasError = conversation.hasError();
    // When there's an error icon, the attachment icon is left of the error
    // icon.
    // When there is not an error icon, the attachment icon is left of the
    // date text.
    // As far as I know, there's no way to specify that relationship in xml.
    if (hasError) {
      attachmentLayout.addRule(RelativeLayout.LEFT_OF, R.id.error);
    } else {
      attachmentLayout.addRule(RelativeLayout.LEFT_OF, R.id.date);
    }

    boolean hasAttachment = conversation.hasAttachment();
    mAttachmentView.setVisibility(hasAttachment ? VISIBLE : GONE);

    // Date
    mDateView.setText(MessageUtils.formatTimeStampString(context, conversation.getDate()));

    // mConversation.ensureThreadId();
    if (mConversation != null) {
      if (conversation.getSimType(mConversation.getThreadId()) == 0)
        mType.setText(context.getString(R.string.card_one));
      else if (conversation.getSimType(mConversation.getThreadId()) == 1)
        mType.setText(context.getString(R.string.card_two));
      else if (conversation.getSimType(mConversation.getThreadId()) == 2) mType.setText("");

    } else {
      mType.setText("");
    }
    // From.
    mFromView.setText(formatMessage());

    // Register for updates in changes of any of the contacts in this
    // conversation.
    ContactList contacts = conversation.getRecipients();

    if (Log.isLoggable(LogTag.CONTACT, Log.DEBUG)) {
      Log.v(TAG, "bind: contacts.addListeners " + this);
    }
    Contact.addListener(this);

    // Subject
    SmileyParser parser = SmileyParser.getInstance();
    mSubjectView.setText(parser.addSmileySpans(conversation.getSnippet()));
    LayoutParams subjectLayout = (LayoutParams) mSubjectView.getLayoutParams();
    // We have to make the subject left of whatever optional items are shown
    // on the right.
    subjectLayout.addRule(
        RelativeLayout.LEFT_OF,
        hasAttachment ? R.id.attachment : (hasError ? R.id.error : R.id.date));

    // Transmission error indicator.
    mErrorIndicator.setVisibility(hasError ? VISIBLE : GONE);

    updateAvatarView();
  }