Android Telephony系统 之 DataConnectionTracker与MobileDataStateTracker之间的通信

来源:互联网 发布:淘宝售后客服怎么应聘 编辑:程序博客网 时间:2024/05/01 00:09
我们知道DataConnectionTracker是跑在com.android.phone进程中,而MobileDataStateTracker是跑在system_server进程中,那么两者是如何通信的
在DataConnectionTracker的派生类GsmDataConnectionTracker的构造函数的最后一行:
public GsmDataConnectionTracker(PhoneBase p)
      broadcastMessenger();//调用父类DataConnectiontracker的方法
DataConnectionTracker.java
     protected void broadcastMessenger()
        Intent intent = new Intent(DctConstants.ACTION_DATA_CONNECTION_TRACKER_MESSENGER);                                                            
        intent.putExtra(DctConstants.EXTRA_MESSENGER, new Messenger(this));
        mPhone.getContext().sendBroadcast(intent);        //构造一个Messenger,通过intent发送出去   
这个intent,会被MobileDataStateTracker收到,而正是这个Messenger(信使),搭建起了二者通信的桥梁。
既然是进程间通信,必然会存在一个Messenger.aidl接口,那么来看Messenger.aidl的实现:
package android.os;
parcelable Messenger; //这意味Messgenger可以通过parcelable的方式在进程间传输。

那么在一个进程里面,怎么给另外一个进程的Handler发消息,就像那个Handler在自己进程里面跑一样呢。
答案就是IMessenger.aidl接口,看IMessenger.aidl的实现
package android.os;
import android.os.Message;
/** @hide */
oneway interface IMessenger {
    void send(in Message msg);  //那么send接口可以跨进程调用
}

IMessenger的Stub代码,理所应当的在Handler.java中实现。
    private final class MessengerImpl extends IMessenger.Stub {
        public void send(Message msg) {
            Handler.this.sendMessage(msg); //对方的进程,调用send,就是相当于调用本进程的Handler的sendMessage
        }
    }

那么怎么才能调用到这个接口呢,就是Messenger,Messeger对send接口进行的包装,看Messenger的构造方法实现
    public Messenger(Handler target) {
        mTarget = target.getIMessenger();
    }


现在,可以来看MobileDataStateTracker的onReceiver方法
            if (intent.getAction().equals(DctConstants
                    .ACTION_DATA_CONNECTION_TRACKER_MESSENGER)) {
                if (VDBG) log(mApnType + " got ACTION_DATA_CONNECTION_TRACKER_MESSENGER");
                mMessenger =
                    intent.getParcelableExtra(DctConstants.EXTRA_MESSENGER);  //取出Messager实例
                AsyncChannel ac = new AsyncChannel();
                ac.connect(mContext, MobileDataStateTracker.this.mHandler, mMessenger);  //构造一个AsyncChannel,把自己的Handler与Messenger联系起来,也就是跟DataConnectionTracker联系起来。
            } 

在来看AsyncChannel的connect实现:
framework/base/core/java/com/android/internal/util/AsyncChannel.java
public void connect(Context srcContext, Handler srcHandler, Messenger dstMessenger)
     connected(srcContext, srcHandler, dstMessenger); //构造一个srcMessenger,与MobileDataStateTracker绑定起来
     replyHalfConnected(STATUS_SUCCESSFUL); //给MoblieDataStateTracker发一个,告诉MobileDataStateTracker,我们已经连接一半了
     
那么MoblieDataStateTracker收到这个CMD之后,是怎么处理的。
public void handleMessage(Message msg)
                  if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
                        if (VDBG) {
                            mMdst.log("MdstHandler connected");
                        }
                        mMdst.mDataConnectionTrackerAc = (AsyncChannel) msg.obj; //这个obj其实就是刚在构造的AsyncChannel
                    } 
那么这个通道已经建立起来了。

当ConnectivityService调用MoblieDataStateTracker的setUserDataEnable方法的时候(用户在设置里面把移动数据取消勾选)
MobileDataStateTracker.java
     public void setUserDataEnable(boolean enabled)
          final AsyncChannel channel = mDataConnectionTrackerAc;
          channel.sendMessage(DctConstants.CMD_SET_USER_DATA_ENABLE,
                    enabled ? DctConstants.ENABLED : DctConstants.DISABLED); //构造一个DctConstants.CMD_SET_USER_DATA_ENABLE消息

看AsyncChannel怎么处理
public void sendMessage(Message msg)
     msg.replyTo = mSrcMessenger;
     mDstMessenger.send(msg);  //这里看出,把那个消息发给了DataConnecionTracker。

再来看DataConnectionTracker是如何处理的
public void handleMessage(Message msg)
            case DctConstants.CMD_SET_USER_DATA_ENABLE: {
                final boolean enabled = (msg.arg1 == DctConstants.ENABLED) ? true : false;
                onSetUserDataEnabled(enabled);  //这里做开启数据,断开数据的操作
                break;
            }
          
可以看出,正是Handler的跨进程传输特型,才让AsyncChannel能够将两个进程的Handler联系起来。

From: http://blog.csdn.net/yinlijun2004/article/details/9570199

原创粉丝点击