高通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 7.0短信草稿保存流程

短信应用,当输入联系人并且短信内容不为空,在没有发送的情况下退出短信界面,则会进行短信草稿保存,以便下次重新进入会话界面可以重新加载,进行重新编辑或者发送。 我们现在就来分析其流程: Co...

日志分析找到弹出toast的应用

我们有时候手机在运行过程中,触发某些条件,会弹出toast,但是有时候会对我们造成困扰,因为不是我们应用弹出来,但是发生的场景又是在我们应用操作过程中发现的。所以这个时候就需要对日志进行分析,找出正在...

高通Android 4.4 彩信发送流程

MMS send flow in QCOM MMS发送流程图 Key Point 1:在点击短信界面的发送button(高通插入双卡后有两个botton)后,会进入ComposeMessag...
  • vvvvcp
  • vvvvcp
  • 2015年04月13日 11:16
  • 879

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

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

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

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

ActiveMQ的消息重发机制

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

IEC104规约的超时和报文丢失重发的处理机制

104规约的超时的理解 超时的定义 参数    默认值    备注    选择值 t0    30s    连接建立的超时     t1    15s    发送或...

Java UDP 重发机制

Java UDP 重发机制

Android彩信发送

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

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

假如现在我手里有一个很重要的消息的,想要发给一个人,但是很不幸,消息发送失败了。这时候怎么办呢怎么解决这种尴尬的情况,这时候我们可以利用activeMQ的 消息重发机制(RedeliveryPoli...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:高通android 7.0彩信重发机制
举报原因:
原因补充:

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