SIM卡 --- 联系人查询过程回调处理

Posted Achillisjack

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SIM卡 --- 联系人查询过程回调处理相关的知识,希望对你有一定的参考价值。

1.2回调处理

回调主要是通过消息的形式,

首先是IccFileHandler的EVENT_EFEXT1_LINEAR_RECORD_SIZE_DONE 消息,

然后是AdnRecordCache的EVENT_LOAD_ALL_ADN_LIKE_DONE消息,

最后处理IccPhoneBookInterfaceManager的EVENT_LOAD_DONE消息时唤醒子线程。

回调处理的流程图如下,


IccFileHandler的handleMessage方法对EVENT_EFEXT1_LINEAR_RECORD_SIZE_DONE 消息处理如下,

ar = (AsyncResult)msg.obj;  // 获取查询结果信息
lc = (LoadLinearFixedContext) ar.userObj;
result = (IccIoResult) ar.result;
response = lc.mOnLoaded;
•••
sendResult(response, recordSize, null);

sendResult方法逻辑如下,

AsyncResult.forMessage(response, result, ex);
response.sendToTarget(); // 发送消息

发送的消息是AdnRecordCache的EVENT_LOAD_ALL_ADN_LIKE_DONE消息,

AdnRecordCache的handleMessage方法对该消息处理逻辑如下,

1,获取查询结果,

ar = (AsyncResult) msg.obj;
efid = msg.arg1;
extensionEf = msg.arg2;
ArrayList<Message> waiters;

2,出队列

waiters = mAdnLikeWaiters.get(efid);
mAdnLikeWaiters.delete(efid);

3,调用notifyWaiters方法发送回调消息,

notifyWaiters(waiters, ar);

notifyWaiters方法如下,

for (int i = 0, s = waiters.size() ; i < s ; i++) 
    Message waiter = waiters.get(i);
AsyncResult.forMessage(waiter, ar.result, ar.exception);
    waiter.sendToTarget();

这里的消息就是 IccPhoneBookInterfaceManager的EVENT_LOAD_DONE消息, IccPhoneBookInterfaceManager的handleMessage方法对EVENT_LOAD_DONE消息处理如下,

ar = (AsyncResult)msg.obj; // 获取结果
synchronized (mLock) 
mRecords = (List<AdnRecord>) ar.result; // 最后返回的是这个结果
•••
notifyPending(ar); // 唤醒子线程

notifyPending方法如下,

mLock.notifyAll();

唤醒子线程,这样又回到了IccPhoneBookInterfaceManager的getAdnRecordsInEf方法,该方法后面的逻辑如下,

1,如果返回结果为空,则递归调用getAdnRecordsInEf方法,只是参数不同,

if (mRecords == null && efid == IccConstants.EF_PBR && !mAdnCache.isPbrPresent()) 
   logd("getAdnRecordsInEF: Load from EF_ADN as pbr is not present");
   mForceAdnUsage = true;
   return getAdnRecordsInEf(IccConstants.EF_ADN);

2,如果有返回结果,直接返回,

return mRecords;

mRecords 就是在handleMessage方法中赋值的。

 

虽然, IccProvider数据库的查询过程都是这一系列操作都是在phone进程中进行,但是AdnRecord还是实现了Parcelable,

public class AdnRecord implements Parcelable 

也就是说,还是可以进行跨进程查询的。

小结:

1,SIM卡联系人的查询都是通过RIL库发送指令到modem侧进行查询的,因此,看不到SIM卡联系人的数据库。

2,并且,在IccPhoneBookInterfaceManager的getAdnRecordsInEf方法中通过子线程的休眠,UI线程的唤醒进行同步。

3,在整个过程中,使用了大量的消息回调处理机制。

以上是关于SIM卡 --- 联系人查询过程回调处理的主要内容,如果未能解决你的问题,请参考以下文章

华为手机装了手机卡为啥总显示没有sm

Android - 创建新的 SIM 卡联系人

SIM卡 --- 联系人增加/删除/更新 分析

esp32读取sim

以编程方式阅读 Android 中的 Sim 联系人?

Sim 联系人不会显示