高通android 7.0彩信重发机制

来源:互联网 发布:ubuntu ssh root 登录 编辑:程序博客网 时间:2024/06/05 08:43
彩信的重发机制
跟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
接着就是继续之前描述的彩信流程了。




原创粉丝点击