高通android 7.0彩信重发机制

原创 2017年09月12日 09:02:04
彩信的重发机制
跟DefaultRetryScheme这个有关
<integer-array name="retry_scheme">
        <item>60000</item> 1分钟
        <item>300000</item> 5分钟
        <item>600000</item> 10分钟
        <item>1800000</item> 30分钟
    </integer-array>
单位是毫秒


getWaitingInterval

RetryScheduler.java是单例模式

scheduleRetry
update



public SendTransaction(Context context,
            int transId, TransactionSettings connectionSettings, String uri) {
        super(context, transId, connectionSettings);
        mSendReqURI = Uri.parse(uri);
        mId = uri;

        // Attach the transaction to the instance of RetryScheduler.
        attach(RetryScheduler.getInstance(context));
    } 
public void attach(Observer observer) {
        detach(observer);
        mObservers.add(observer);
    }
attach就是注册监听器
所以当调用notifyObservers就会出发调用update

SendTransaction在run的最后
finally {
            if (mTransactionState.getState() != TransactionState.SUCCESS) {
                mTransactionState.setState(TransactionState.FAILED);
                mTransactionState.setContentUri(mSendReqURI);
                Log.e(TAG, "Delivery failed.");
            }
            notifyObservers();
 }

 
现在我们来看下RetryScheduler的update方法
public void update(Observable observable) {
        Uri uri = null;
        Transaction t = (Transaction) observable;
        try {

            if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
                Log.v(TAG, "[RetryScheduler] update " + observable);
            }

            // We are only supposed to handle M-Notification.ind, M-Send.req
            // and M-ReadRec.ind.
            if ((t instanceof NotificationTransaction)
                    || (t instanceof RetrieveTransaction)
                    || (t instanceof ReadRecTransaction)
                    || (t instanceof SendTransaction)) {
                try {
                    TransactionState state = t.getState();
                    if (state.getState() == TransactionState.FAILED) {//如果是失败状态,获取Uri,然后启动重试
                        uri = state.getContentUri();
                        if (uri != null) {
                            scheduleRetry(mContext, uri);
                        }
                    }
                } finally {
                    t.detach(this);
                }
            }
        } finally {
            setRetryAlarm(mContext, uri);//这个设置alarm来进行重发
            Log.d(TAG, "set retry alarm");
        }
    }

scheduleRetry 这个方法是对pending_msgs表需要重发的字段进行更新,并且进行检测
我们还是以发送失败重发为例。
发送失败的话,其在pending_msgs仍然会有记录,
uriBuilder.appendQueryParameter("message", String.valueOf(msgId)); 查找到发送失败的msgId对应的pending_msgs中的记录
int retryIndex = cursor.getInt(cursor.getColumnIndexOrThrow(
                            PendingMessages.RETRY_INDEX)) + 1;
retry_index字段表示已经重试的次数
boolean isRetryDownloading =
                            (msgType == PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND);下载失败也会进行重试的,这个我们略过,读者自己看代码

long retryAt = current + scheme.getWaitingInterval();
values.put(PendingMessages.DUE_TIME, retryAt); 所以due_time字段是下次重发的时间


注意,context是TransactionService的context
public static void setRetryAlarm(Context context, Uri mmsUrl) {
        Cursor mmsCursor = PduPersister.getPduPersister(context).getPendingMessages(
                Long.MAX_VALUE);
        if (mmsCursor != null) {
            try {
                Cursor cursor = getMmsCursor(mmsCursor, mmsUrl);
                if (cursor != null) {
                    // The result of getPendingMessages() is order by due time.
                    long retryAt = cursor.getLong(cursor.getColumnIndexOrThrow(
                            PendingMessages.DUE_TIME));

                    Intent service = new Intent(TransactionService.ACTION_ONALARM,
                            null, context, TransactionService.class);
                    PendingIntent operation = PendingIntent.getService(
                            context, 0, service, PendingIntent.FLAG_ONE_SHOT);
                    AlarmManager am = (AlarmManager) context.getSystemService(
                            Context.ALARM_SERVICE);
                    am.setExact(AlarmManager.RTC, retryAt, operation);

                    if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
                        Log.v(TAG, "Next retry is scheduled at"
                                + (retryAt - System.currentTimeMillis()) + "ms from now");
                    }
                }
            } finally {
                mmsCursor.close();
            }
        }
    }
所以重发机制是设置了alarm。

TransactionService的ACTION_ONALARM
onNewIntent
接着就是继续之前描述的彩信流程了。




版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

android短彩信幻灯片异步加载机制

记不清是android 4.0之后还是4.1之后,浏览信息时,彩信幻灯片不再随着信息内容一并显示,而是在信息内容显示后,开启后台线程,异步加载彩信幻灯片,加载完毕之后再显示附件。为什么要这么设计那?主...

项目难题之编程实现数据不对重发的机制

ARM接收PC机通过串口发来的数据,数据打包成帧的形式,有针头针尾,我要实现的功能是:ARM通过检验帧头针尾是否正确,决定是否请求PC机重新发送上一帧的数据。 我们知道汇编中有调到特定位置的程序的功能...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

ActiveMQ的消息重发机制

本文以ActiveMQ最新的5.10版本为准。        大家知道,JMS规范中,Message消息头接口中有setJMSRedelivered(boolean redelivered)和getJ...

Spring ActiveMQ 整合(二): 重发机制(消息发送失败后的重新发送)

假如现在我手里有一个很重要的消息的,想要发给一个人,但是很不幸,消息发送失败了。这时候怎么办呢怎么解决这种尴尬的情况,这时候我们可以利用activeMQ的 消息重发机制(RedeliveryPoli...

Java UDP 重发机制

Java UDP 重发机制

Android彩信发送

第一,网络切换问题,只能手动切换gprs和apn后才能发送成功。 第二,pdu打包问题,pdu打包方法android源码里有,但没有提供接口,添加资源时候要注意资源类型和格式。 第三,注意区分不同...

微信开发页面请求重发问题

偶然的一次因为项目再生产上出了问题发现的 对于微信浏览器(安卓版本)如果页面请求结束等待响应时间超过10S微信浏览器会认为没响应,并主动重发上条ajax请求 对于该问题,暂时没想到解决方案,再生产中是...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)