来电呼入时的各种信息显示都是在CallCard.java中实现的,其中的updateDisplayForPerson是主角。updateDisplayForPerson会根据电话的当前状态来更改名字号码等信息的显示。图片的替换代码如下:
ContactsAsyncHelper.updateImageViewWithContactPhotoAsync( info, 0, this, call, getContext(), mPhoto, personUri, R.drawable.picture_unknown);
personUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, info.person_id);
R.drawable.picture_unknown则是系统默认的显示图片,如果查询不到相应personUri的大头贴信息,就会使用该图片。图片的加载是在ContactsAsynHelper.java中实现的。updateImageViewWithContactPhotoAsync方法的参数比较多,主要用于参数设定,消息发送:
public static final void updateImageViewWithContactPhotoAsync(CallerInfo info, int token, OnImageLoadCompleteListener listener, Object cookie, Context context, ImageView imageView, Uri person, int placeholderImageResource) { if (person == null) { if (DBG) Log.d(LOG_TAG, "target image is null, just display placeholder."); imageView.setVisibility(View.VISIBLE); imageView.setImageResource(placeholderImageResource); return; } // Added additional Cookie field in the callee to handle arguments // sent to the callback function. // setup arguments WorkerArgs args = new WorkerArgs(); args.cookie = cookie; args.context = context; args.view = imageView; args.uri = person; args.defaultResource = placeholderImageResource; args.listener = listener; args.info = info; // setup message arguments Message msg = sThreadHandler.obtainMessage(token); msg.arg1 = EVENT_LOAD_IMAGE; msg.obj = args; if (DBG) Log.d(LOG_TAG, "Begin loading image: " + args.uri + ", displaying default image for now."); // set the default image first, when the query is complete, we will // replace the image with the correct one. if (placeholderImageResource != -1) { imageView.setVisibility(View.VISIBLE); imageView.setImageResource(placeholderImageResource); } else { imageView.setVisibility(View.INVISIBLE); } // notify the thread to begin working sThreadHandler.sendMessage(msg); }
private class WorkerHandler extends Handler {
public WorkerHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
WorkerArgs args = (WorkerArgs) msg.obj;
switch (msg.arg1) {
case EVENT_LOAD_IMAGE:
InputStream inputStream = null;
try {
inputStream = Contacts.openContactPhotoInputStream(
args.context.getContentResolver(), args.uri, true);
} catch (Exception e) {
Log.e(LOG_TAG, "Error opening photo input stream", e);
}
if (inputStream != null) {
args.result = Drawable.createFromStream(inputStream, args.uri.toString());
if (DBG) Log.d(LOG_TAG, "Loading image: " + msg.arg1 +
" token: " + msg.what + " image URI: " + args.uri);
} else {
args.result = null;
if (DBG) Log.d(LOG_TAG, "Problem with image: " + msg.arg1 +
" token: " + msg.what + " image URI: " + args.uri +
", using default image.");
}
break;
default:
}
// send the reply to the enclosing class.
Message reply = ContactsAsyncHelper.this.obtainMessage(msg.what);
reply.arg1 = msg.arg1;
reply.obj = msg.obj;
reply.sendToTarget();
}
}
根据参数中的uri获得输入流,然后根据该输入流查询得到图片,并将图片赋值给result。然后当reply.sendToTarget()方法执行后,会跳转到WorkerHandler类外部的handleMessage方法,此方法和类内部的handleMessage方法完全不同。最后在外部的handleMessage方法中设定图片资源:
if (args.result != null) { args.view.setVisibility(View.VISIBLE); args.view.setImageDrawable((Drawable) args.result); // make sure the cached photo data is updated. if (args.info != null) { args.info.cachedPhoto = (Drawable) args.result; }
private static final boolean showCachedImage(ImageView view, CallerInfo ci) { if ((ci != null) && ci.isCachedPhotoCurrent) { if (ci.cachedPhoto != null) { log("person id is " + ci.person_id); log("showCachedImage: using the cachedPhoto!"); showImage(view, ci.cachedPhoto); } else { log("showCachedImage: using picture_unknown!"); showImage(view, R.drawable.picture_unknown); } return true; } log("showCachedImage: return false!"); return false; }