前面已经RILD进行了分析,现在就对RILJ进行简单的分析
1.绪论
所有上层对RIL层的请求,最终都需要在RILJ中转换为RIL层可识别的命令,然后通过Socket通道传输下去
同时,RIL层据的上报,也要通过RILJ进行解码,还原为上层容易识别的格式
RILJ有两个主要特点:
1、开启了两个独立线程分别负责发送数据和接收数据
2、数据的发送和接收是异步的,采用令牌系统来找到当初的请求者
2.RILRequest令牌系统
class RILRequest {
........
private static Object sPoolSync = new Object(); //sPool分配与回收的互斥锁
private static RILRequest sPool = null;//代表了一个RILRequest对象的链表
private static int sPoolSize = 0;// 当前sPool所在链表的长度
private static final int MAX_POOL_SIZE = 4; // sPool的最大个数
........
int mSerial; //令牌,每生成(obtain)一个新的请求,都将产生一个递增的,唯一的mSerial。当从RILC中得到一个数据后,我们就是通过mSerial找到当初发送这个请求的对象
int mRequest; // 请求码,需要和RIL层中的ril_commands.h文件内定义的请求码一致
Message mResult; // 生成当前请求的请求者。从RILC中得到数据后,需要把数据处理后返回给mResult指向的对象
Parcel mParcel; // 附加数据
RILRequest mNext; // 链表结构,代表下一个RILRequest
........
static RILRequest obtain(int request, Message result) { // 生成一个RILRequest的消息对象
// 如果sPool所在链表不为空则从该链表中获取一个RILRequest对象,否则新构造一个
RILRequest rr = null;
synchronized(sPoolSync) {
if (sPool != null) {
rr = sPool;
sPool = rr.mNext;
rr.mNext = null;
sPoolSize--;
}
}
if (rr == null) {
rr = new RILRequest();
}
// 初始化令牌mSerial,AtomicInteger的getAndIncrement可保证当前请求的令牌是唯一的,递增的
rr.mSerial = sNextSerial.getAndIncrement();
rr.mRequest = request;// 初始化请求码mRequest
rr.mResult = result;// 初始化请求者mResult
rr.mParcel = Parcel.obtain();
if (result != null && result.getTarget() == null) {
throw new NullPointerException("Message target must not be null");
}
// 写入请求码与请求者
rr.mParcel.writeInt(request);
rr.mParcel.writeInt(rr.mSerial);
return rr;
}
void release() { // 释放资源
synchronized (sPoolSync) {
if (sPoolSize < MAX_POOL_SIZE) { // 如果当前sPool链表还没有满,则将当前RILRequest对象添加到链表中以便复用
mNext = sPool;
sPool = this;
sPoolSize++;
mResult = null;
}
}
}
private RILRequest() {} // 构造函数,内容为空
static void resetSerial() {........} // 重置令牌
String serialString() {........} // 生成包含mSerial的字串,主要用于打印Log
void onError(int error, Object ret) {........} // 异常处理
}
3.发送子线程
1、如何把数据发送到mSenderThread中;
// 创建mSender的时候就是用mSenderThread的looper来创建的,即用mSender发送消息即可发送到mSenderThread中
public RIL(Context context, int preferredNetworkType, int cdmaSubscription) {
super(context);
........
//发送子线程
mSenderThread = new HandlerThread("RILSender");
mSenderThread.start();
Looper looper = mSenderThread.getLooper();
//mSender是发送子线程的Handler,通过他可以发送数据
mSender = new RILSender(looper);
........
//接收子线程
mReceiver = new RILReceiver();
mReceiverThread = new Thread(mReceiver, "RILReceiver");
mReceiverThread.start();
........
}
// 发送短消息
public void sendSMS (String smscPDU, String pdu, Message result) {
// 构建一个请求
RILRequest rr = RILRequest.obtain(RIL_REQUEST_SEND_SMS, result);
constructGsmSendSmsRilRequest(rr, smscPDU, pdu);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
//发送
send(rr);
}
........
private void send(RILRequest rr) {
Message msg;
// 如果Socket通道还没有打开
if (mSocket == null) {
rr.onError(RADIO_NOT_AVAILABLE, null);
rr.release();
return;
}
// 生成mSender的消息
msg = mSender.obtainMessage(EVENT_SEN