Android Phone模块 三
来源:互联网 发布:wind软件使用 编辑:程序博客网 时间:2024/05/21 02:50
RIL
public RIL(Context context, int preferredNetworkType, int cdmaSubscription,int phoneId) {super(context);mCdmaSubscription = cdmaSubscription;mPreferredNetworkType = preferredNetworkType;mPhoneType = RILConstants.NO_PHONE;mPhoneId = phoneId;if (mPhoneId != PhoneFactory.DEFAULT_PHONE_ID) {SOCKET_NAME_RIL = SOCKET_NAME_RIL + phoneId;}PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);mWakeLock.setReferenceCounted(false);mWakeLockTimeout = SystemProperties.getInt(TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT,DEFAULT_WAKE_LOCK_TIMEOUT);mRequestMessagesPending = 0;mRequestMessagesWaiting = 0;//创建ril发送线程mSenderThread = new HandlerThread("RILSender");mSenderThread.start();Looper looper = mSenderThread.getLooper();mSender = new RILSender(looper);ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);if (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false) {riljLog("Not starting RILReceiver: wifi-only");} else {riljLog("Starting RILReceiver");//创建接收线程mReceiver = new RILReceiver();mReceiverThread = new Thread(mReceiver, "RILReceiver");mReceiverThread.start();IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_SCREEN_ON);filter.addAction(Intent.ACTION_SCREEN_OFF);context.registerReceiver(mIntentReceiver, filter);}}RIL线程模型:
RILSender
当上层需要向rild服务发送请求时,通过RIL的send函数来完成。
public void handleMessage(Message msg) {RILRequest rr = (RILRequest) (msg.obj);RILRequest req = null;switch (msg.what) {case EVENT_SEND:boolean alreadySubtracted = false;try {LocalSocket s;s = mSocket;if (s == null) {rr.onError(RADIO_NOT_AVAILABLE, null);rr.release();if (mRequestMessagesPending > 0)mRequestMessagesPending--;alreadySubtracted = true;return;}synchronized (mRequestsList) {mRequestsList.add(rr);mRequestMessagesWaiting++;}if (mRequestMessagesPending > 0)mRequestMessagesPending--;alreadySubtracted = true;byte[] data;data = rr.mp.marshall();rr.mp.recycle();rr.mp = null;if (data.length > RIL_MAX_COMMAND_BYTES) {throw new RuntimeException("Parcel larger than max bytes allowed! "+ data.length);}// parcel length in big endiandataLength[0] = dataLength[1] = 0;dataLength[2] = (byte) ((data.length >> 8) & 0xff);dataLength[3] = (byte) ((data.length) & 0xff);s.getOutputStream().write(dataLength);s.getOutputStream().write(data);} catch (IOException ex) {Log.e(LOG_TAG, "IOException", ex);req = findAndRemoveRequestFromList(rr.mSerial);if (req != null || !alreadySubtracted) {rr.onError(RADIO_NOT_AVAILABLE, null);rr.release();}} catch (RuntimeException exc) {Log.e(LOG_TAG, "Uncaught exception ", exc);req = findAndRemoveRequestFromList(rr.mSerial);if (req != null || !alreadySubtracted) {rr.onError(GENERIC_FAILURE, null);rr.release();}} finally {releaseWakeLockIfDone();}if (!alreadySubtracted && mRequestMessagesPending > 0) {mRequestMessagesPending--;}break;case EVENT_WAKE_LOCK_TIMEOUT:synchronized (mWakeLock) {if (mWakeLock.isHeld()) {if (mRequestMessagesWaiting != 0) {mRequestMessagesWaiting = 0;}if (mRequestMessagesPending != 0) {mRequestMessagesPending = 0;}mWakeLock.release();}}break;}}
写入rild套接字的数据为:
发送步骤:
1. 生成RILRequest,此时将生成m_Serial(请求的Token)并将请求号,数据,及其Result Message 对象填入到RILRequest中
2. 使用send将RILRequest打包到EVENT_SEND消息中发送到到RIL Sender Handler
3. RilSender 接收到EVENT_SEND消息,将RILRequest通过套接口发送到RILD,同时将RILRequest保存在mRequest中以便应答消息的返回。
RILReceiver
public void run() {int retryCount = 0;try {for (;;) {LocalSocket s = null;LocalSocketAddress l;try {//创建socket并连接到rilds = new LocalSocket();l = new LocalSocketAddress(SOCKET_NAME_RIL,LocalSocketAddress.Namespace.RESERVED);s.connect(l);} catch (IOException ex) {try {if (s != null) {s.close();}} catch (IOException ex2) {// ignore failure to close after failure to connect}if (retryCount == 8) {Log.e(LOG_TAG, "Couldn't find '" + SOCKET_NAME_RIL+ "' socket after " + retryCount+ " times, continuing to retry silently");} else if (retryCount > 0 && retryCount < 8) {Log.i(LOG_TAG, "Couldn't find '" + SOCKET_NAME_RIL+ "' socket; retrying after timeout");}try {Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);} catch (InterruptedException er) {}retryCount++;continue;}retryCount = 0;mSocket = s;Log.i(LOG_TAG, "Connected to '" + SOCKET_NAME_RIL + "' socket");int length = 0;try {InputStream is = mSocket.getInputStream();//循环从socket中读取消息for (;;) {Parcel p;length = readRilMessage(is, buffer);if (length < 0) {break;}p = Parcel.obtain();p.unmarshall(buffer, 0, length);p.setDataPosition(0);processResponse(p);p.recycle();}} catch (java.io.IOException ex) {Log.i(LOG_TAG, "'" + SOCKET_NAME_RIL + "' socket closed",ex);} catch (Throwable tr) {Log.e(LOG_TAG, "Uncaught exception read length=" + length+ "Exception:" + tr.toString());}//socket连接断开,请求所有请求并重新连接Log.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL+ "' socket");setRadioState(RadioState.RADIO_UNAVAILABLE);try {mSocket.close();} catch (IOException ex) {}mSocket = null;RILRequest.resetSerial();clearRequestsList(RADIO_NOT_AVAILABLE, false);}} catch (Throwable tr) {Log.e(LOG_TAG, "Uncaught exception", tr);}notifyRegistrantsRilConnectionChanged(-1);}
接收步骤
1. 分析接收到的Parcel,根据类型不同进行处理。
2. 根据数据中的Token(mSerail),反查mRequest,找到对应的请求信息。
3. 将是接收到的数据转换成结果数据。
4. 将结果放在RequestMessage中发回到请求的发起者。
- Android Phone模块 三
- android phone 模块分析
- android phone 模块分析
- android phone 模块分析
- android phone 模块分析
- android phone模块流程
- android phone 模块分析
- Android Phone模块 一
- Android Phone模块 二
- Android Phone模块 一
- Android Phone模块 二
- Android Phone 模块3
- Android Phone模块 一
- Android Phone模块
- Android Phone模块详解
- Android Lollipop Phone模块学习计划
- Android 5.0 Phone 模块介绍
- android -- phone (三)来电流程
- .net 2010 chart控件绘制饼状图
- 自己实现的对象池
- 内存分析和优化总结
- 高并发数据缓存池(基于EHcache)
- JS模拟alert与confrim 对话框
- Android Phone模块 三
- http://www.360doc.com/content/10/0905/21/1066008_51463300.shtml
- 并查集详解 (转)
- Android系统中的输入输出设备
- 黑马程序员--入门基础二
- DisplayTag详解
- mongodb的mapreduce的分组统计
- iOS: bundle name, bundle display name, bundle identifier...
- Response.Redirect(),Server.Transfer(),Server.Execute()的区别与网站优化