RIL 机制---消息从RILJ到RIL

来源:互联网 发布:如何选基金 知乎 编辑:程序博客网 时间:2024/06/05 02:51

RILJ发送子线程需要关注两点:

1、如何把数据发送到mSenderThread中;

2、mSenderThread是如何把请求发送给RIL的。

在创建mSenderThread线程的时候,先是通过getLooper得到子线程的Looper,

然后用这个Looper去创建了Handler对象,因此得到的这个Handler对象就是子线程的Handler,也就是RILSender对象。

4.1 Send方法

各种发送消息的方法最后都要通过send方法来发送,例如进行拨号, dial方法如下,

@Override    public void    dial(String address, int clirMode, UUSInfo uusInfo, Message result) {        RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result);        rr.mParcel.writeString(address);        rr.mParcel.writeInt(clirMode);        if (uusInfo == null) {            rr.mParcel.writeInt(0); // UUS information is absent        } else {            rr.mParcel.writeInt(1); // UUS information is present            rr.mParcel.writeInt(uusInfo.getType());            rr.mParcel.writeInt(uusInfo.getDcs());            rr.mParcel.writeByteArray(uusInfo.getUserData());        }        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));        send(rr);    }

使用RIL_REQUEST_DIAL 表示拨号的消息码。

通过mSender对象生成(obtainMessage)了一个EVENT_SEND的消息,

同时把请求包装为RILRequest对象,连同EVENT_SEND消息一同发送(sendToTarget)给了子线程。

4.2 RILSender处理

RILSender中handleMessage方法有关EVENT_SEND消息处理如下,

case EVENT_SEND:       try {              LocalSocket s; s = mSocket;if (s == null) { rr.onError(RADIO_NOT_AVAILABLE, null);                     rr.release();                     decrementWakeLock();                     return;               }synchronized (mRequestList) {                     mRequestList.append(rr.mSerial, rr);               }byte[] data;data = rr.mParcel.marshall();               rr.mParcel.recycle();               rr.mParcel = null;               if (data.length > RIL_MAX_COMMAND_BYTES) {//data长度不能超过8kb                    throw new RuntimeException(                                    "Parcel larger than max bytes allowed! "                                                          + data.length);                        }                        // parcel length in big endian                    // byte[] dataLength = new byte[4];                  dataLength[0] = dataLength[1] = 0;                  dataLength[2] = (byte)((data.length >> 8) & 0xff);                 dataLength[3] = (byte)((data.length) & 0xff);                        //Rlog.v(RILJ_LOG_TAG, "writing packet: " + data.length + " bytes");                 s.getOutputStream().write(dataLength);//发送data长度信息                 s.getOutputStream().write(data);//发送数据。                    } catch (IOException ex) {                        Rlog.e(RILJ_LOG_TAG, "IOException", ex);                        req = findAndRemoveRequestFromList(rr.mSerial);                        // make sure this request has not already been handled,                        // eg, if RILReceiver cleared the list.                        if (req != null) {                            rr.onError(RADIO_NOT_AVAILABLE, null);                            rr.release();                            decrementWakeLock();                        }                    } catch (RuntimeException exc) {                        Rlog.e(RILJ_LOG_TAG, "Uncaught exception ", exc);                        req = findAndRemoveRequestFromList(rr.mSerial);                        // make sure this request has not already been handled,                        // eg, if RILReceiver cleared the list.                        if (req != null) {                            rr.onError(GENERIC_FAILURE, null);                            rr.release();                            decrementWakeLock();                        }                    }      break;

发送的过程很简单,就是通过Socket通道把数据长度(dataLength)信息和数据(data)发送出去。

小结:RILJ首先对消息进行封装,然后在发送线程中通过Socket通道把数据长度信息和数据发送出去。

RILJ和rild守护进程一次通信的数据不大于8kb,通信的消息码分别保存在RILConstants.java和ril.h中。


                                             
0 0
原创粉丝点击