关于Synchronized方法使用问题
2017-11-21 20:45
267 查看
前言
今天遇到一个问题(项目),客户测试,插入2张SIM卡重启,只有卡1收到短信。正常情况是收到2条短信,此问题是偶现,概率不高。代码
关键代码如下,通过for循环每张卡发送短信。List<SubscriptionInfo> subInfoList = SubscriptionManager.from( mContext).getActiveSubscriptionInfoList(); Log.d(TAG, "subInfoList size " + subInfoList.size()); for (SubscriptionInfo subscriptionInfo : subInfoList) { .... sendMms(msg, getReturnPhoneNumber(slot_imei, sim_number)); }
sendMms方法实现:
private void sendMms(Message msg, String sendText) { int subid = msg.getData().getInt(Sms.SUBSCRIPTION_ID); ... SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subid); PendingIntent pendInt = createSendIntent(subid, sendText, tiems); String encrypt_text = encrypt(sendText); if (encrypt_text.length() > 70) { ArrayList<String> parts = smsManager.divideMessage(encrypt_text); ArrayList<PendingIntent> list = new ArrayList<PendingIntent>(); list.add(pendInt); smsManager.sendMultipartTextMessage(address, scAddress, parts, list, null); } else { smsManager.sendTextMessage(address, scAddress, encrypt_text, pendInt, null); } }
日志分析
日志显示11-16 14:22:07.713052 1649 2745 D LockChangeReceiver: subInfoList size 2 11-16 14:22:07.734687 1649 2745 D LockChangeReceiver: last_sim iccid:89911100185008968471 current iccid:89911190185136664852 11-16 14:22:07.788860 1649 2745 D LockChangeReceiver: subid: 7 address +917065333399 scAddress: +919811009998 sendText: *CRED* IMEI: 862893009046736 NEW MOBILE NUMBER: 11-16 14:22:07.799236 1649 2745 D LockChangeReceiver: encryptedMsg: cwU4Yp/CTK97F7TnAT39McKzpfNW/qM3fEbCepmUIADsgWN3xOzmeUPXJgzMFO9Z 11-16 14:22:07.913115 1649 2745 D LockChangeReceiver: last_sim iccid:8991101505026689073f current iccid:89911190185060300424 11-16 14:22:08.004434 1649 2745 D LockChangeReceiver: subid: 3 address +917065333399 scAddress: +919811009998 sendText: *CRED* IMEI: 862893009046736 NEW MOBILE NUMBER: 11-16 14:22:08.008499 1649 2745 D LockChangeReceiver: encryptedMsg: cwU4Yp/CTK97F7TnAT39McKzpfNW/qM3fEbCepmUIADsgWN3xOzmeUPXJgzMFO9Z
上面的日志显示,sim 卡 subid 3,7都发送了短信出去。
发送结果
11-16 14:22:36.926676 1649 1649 D LockChangeReceiver: action: com.lava.action.resend_msg 11-16 14:22:36.926924 1649 1649 W LockChangeReceiver: 11-16 14:22:36.926924 1649 1649 W LockChangeReceiver: send msg result 34 11-16 14:22:36.927063 1649 1649 W LockChangeReceiver: Bundle[{msg_ref_num=34, sub_id=3, pdu_size=77, body=*CRED* IMEI: 862893009046736 NEW MOBILE NUMBER:, send_times=0}] 11-16 14:22:36.927194 1649 1649 W LockChangeReceiver: send msg success subid 3 body:*CRED* IMEI: 862893009046736 NEW MOBILE NUMBER: 11-16 14:22:37.964181 1649 1649 D LockChangeReceiver: action: com.lava.action.resend_msg 11-16 14:22:37.964313 1649 1649 W LockChangeReceiver: 11-16 14:22:37.964313 1649 1649 W LockChangeReceiver: send msg result 228 11-16 14:22:37.964431 1649 1649 W LockChangeReceiver: Bundle[{msg_ref_num=228, sub_id=3, pdu_size=77, body=*CRED* IMEI: 862893009046736 NEW MOBILE NUMBER:, send_times=0}] 11-16 14:22:37.964498 1649 1649 W LockChangeReceiver: send msg success subid 3 body:*CRED* IMEI: 862893009046736 NEW MOBILE NUMBER:
从上面的日志可以看出,设备发送了2次短信,但是都是subid = 3的sim卡。所以用户反馈sim卡二未发送短信到服务器平台。
原因分析
1.在方法sendMms里面有一个系统接口调用:SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subid);
此方法实现:
/** * Get the the instance of the SmsManager associated with a particular subscription id * * @param subId an SMS subscription id, typically accessed using * {@link android.telephony.SubscriptionManager} * @return the instance of the SmsManager associated with subId */ public static SmsManager getSmsManagerForSubscriptionId(int subId) { // TODO(shri): Add javadoc link once SubscriptionManager is made public api synchronized(sLockObject) { SmsManager smsManager = sSubInstances.get(subId); if (smsManager == null) { smsManager = new SmsManager(subId); sSubInstances.put(subId, smsManager); } return smsManager; } }
这里面有同步关键字synchronized。当程序执行到这个地方后,由于时间长,至第一个程序没有执行完,第二个程序也执行到这里,此时第一个程序执行完成,返回结果,第二个程序也得到结果,但是是一个的结果。这样2个程序得到同样的结果对象。最终以相同的SIM卡发送短信。
解决方案
在sendMms方法中添加关键字synchronized,避免多程序进入。在for循环中添加延时,每执行一次 暂停N百毫秒
相关文章推荐
- 关于编码过滤的问题,这里使用在web.xml中添加过滤器的方法!
- 关于使用VS.Net2003调试器出现的问题及相关解决方法
- 关于PPT制作和使用的个别问题提出来的解决方法
- 关于在英创em9161板上使用ADO.net连接远程数据库提示 “无法找到 PInvoke dll"dbnetlib.dll"”问题解决方法
- vs2008中使用母版页关于引用*.js的[智能语法提示]和[设置路径]的方法和问题
- CSDN上的一个问题贴(关于内部类在外部类静态方法中使用问题)
- 关于在使用Exchange2003系统时无法向sina,yahoo,hotmail等邮箱发送邮件问题的解决方法
- JavaScript中关于indexOf的使用方法与问题小结
- 关于更改ip后dbconsole服务不能启动(em不能使用)问题的根本解决方法(ZZ)
- 关于"Excel._Worksheet和DocEvents_Event之间存在二义性.将使用方法组"的问题
- Java【多线程知识总结(7)】多线程同步问题-关于synchronized代码块和synchronized方法的应用
- 关于使用VS.Net2003调试器出现的问题及相关解决方法
- 关于安装IE8之后VS2008使用MFC出现问题的解决方法
- JavaScript中关于indexOf的使用方法与问题小结
- 关于使用CreateUserWinzard控件创建用户时出现连接数据库问题的解决方法
- 关于IIS服务启动失败的问题:“IIS提示‘另一个程序正在使用此文件,进程无法访问’”,的解决方法
- 关于ASP.NET“操作必须使用一个可更新的查询”问题的解决方法
- 关于Ibatis中的executeForObject方法使用时,需要考虑空的问题!
- 关于接口使用getType的方法的问题
- 关于使用VS.Net2003调试器出现的问题及相关解决方法 (转)