RILJ发送子线程需要关注两点:
1、如何把数据发送到mSenderThread中;
2、mSenderThread是如何把请求发送给RIL的。
在创建mSenderThread线程的时候,先是通过getLooper得到子线程的Looper,
然后用这个Looper去创建了Handler对象,因此得到的这个Handler对象就是子线程的Handler,也就是RILSender对象。
各种发送消息的方法最后都要通过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)给了子线程。
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中。