android学习日记:来电大头贴显示流程

来电呼入时的各种信息显示都是在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学习日记:来电大头贴显示流程)