来电呼入时的各种信息显示都是在CallCard.java中实现的,其中的updateDisplayForPerson是主角。updateDisplayForPerson会根据电话的当前状态来更改名字号码等信息的显示。图片的替换代码如下:
ContactsAsyncHelper.updateImageViewWithContactPhotoAsync(
info, 0, this, call, getContext(), mPhoto, personUri, R.drawable.picture_unknown);
该方法可以传入CallerInfo信息以及各种参数,然后根据personUri将加载后获得的大头贴图片显示在mPhoto,picture_unknown是mPhoto的默认值。personUri的获取代码如下:
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);
}
当这个方法被执行完毕时,会发送一个包含各种信息的msg,相应的处理handler是在WorkerHandler的handleMessage方法中进行的:
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;
}
最后,在CallCard文件中会根据cachedPhoto来最终显示图片:
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;
}
转载自原文链接, 如需删除请联系管理员。
原文链接:android学习日记:来电大头贴显示流程,转载请注明来源!