RIL源码分析

本文分析了RILJ的工作原理,重点介绍了RILRequest令牌系统,包括如何通过RILRequest.obtain生成请求对象,以及如何通过mSenderThread发送数据。还详细讲解了数据的发送和接收过程,涉及RILSender和RILReceiver两个子线程,以及如何处理RILC返回的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  前面已经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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值