关于Synchronized方法使用问题

前言

今天遇到一个问题(项目),客户测试,插入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百毫秒
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值