快速发送多个广播且部分广播未按时回应的解决方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhujiangtaotaise/article/details/76228646

前言:今天接到一个需求:就是在发出广播后1s内没有相应的话,就返回空的数据,但是等到广播数据回来后就不再处理了。咋一看很容易啊,Handler post delay 1s, 然后,然后设置标志位为true,在处理广播返回数据的时候根据标志位来判断是否要处理。但是我们的场景是可能用户1s内按了触发了3次,其中有的广播在1s内返回数据了,有的1s后才返回数据。所以之前的操作就不灵了。

现在这里介绍下我的思路,下面会对代码进行分析。

我的做法是:维护一个map,key作为每次发送广播的一个标识,value为一个Runnable。然后利用Handler 发送延时1s的任务,在这个任务中主要的工作就是移除map中相应的key对应的任务。如果在1s内返回数据,那么会移除消息队列中的task且移除map中相应的Runnable。

先看XiriHelper.java:

 private Context mContext;
    private static XiriHelper mInstance;
    private OnDataLoadFinish mOnDataLoadFinish ; 


    private XiriHelper(Context context) {
        mContext = context;
        rigesterBroadCast();
    }

    public static XiriHelper getInstance(Context context) {
        if (mInstance == null) {
            synchronized (XiriHelper.class) {
                if (mInstance == null) {
                    mInstance = new XiriHelper(context);
                }
            }
        }
        return mInstance;
    }

    public void setListener(OnDataLoadFinish onDataLoadFinish){
        mOnDataLoadFinish = onDataLoadFinish;
    }

    private void rigesterBroadCast() {
        IntentFilter filter = new IntentFilter();
        filter.addAction("ZJT_XIRI");
        mContext.registerReceiver(dataReceiver, filter);
    }

    private BroadcastReceiver dataReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            int count = (DataManager.mCount-1);
            Log.e("xiri", "XiriHelper::onReceive "+count);
            String data = intent.getStringExtra(""+count);
            //这个index是发送广播的时候传递过来的,标志是第几次发送的广播,然后将这个index回调出去让接收数据的地方知道是第几次发送的广播。
            int index = intent.getIntExtra("INDEX", -1);
            Log.e("xiri", "XiriHelper::onReceive  data: " + data+", index = "+index);
            if(mOnDataLoadFinish != null){
                mOnDataLoadFinish.onFinished(data, index);
            }
        }
    };

    interface OnDataLoadFinish{
        void onFinished(String data, int index);
    }

这个类很简单,就是注册广播和广播接收器,然后定义一个回调,在广播接收到数据的时候利用该回调传递数据。

注册这个数据回调是在DataManager.java中。

package com.example.service;

import java.util.HashMap;
import java.util.Map;

import com.example.service.XiriHelper.OnDataLoadFinish;

import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.util.Log;


public class DataManager {

    private static DataManager mInstance;
    private Context mContext;
    private XiriHelper mHelper;
    public static int mCount = 1;
    private Map<Integer, Runnable> mActiveTask = new HashMap<Integer, Runnable>();
    private Handler mHandler = new Handler();
    private boolean mIsFirster = true;

    private OnDataListener mDataListener;

    private DataManager(Context context){
        mContext = context;
        mHelper = XiriHelper.getInstance(mContext);
        mHelper.setListener(new OnDataLoadFinish() {

            @Override
            public void onFinished(String data, int index) {
                Log.e("xiri", "DataManager :: onFinished >> "+data+" index = "+index);
                if(mActiveTask.get(index) != null){
                    Log.e("xiri", "数据未超时,移除Handler中的任务并清除map中的任务");
                    mHandler.removeCallbacks(mActiveTask.remove(index));
                    if(mDataListener != null){//未超过1s,则返回真实数据
                        mDataListener.onLoad(data);
                    }
                }else{
                    Log.e("xiri", "数据超时,已失效");
                }
            }
        });
    }

    private static synchronized void createInstance(Context context) {
        if (mInstance == null) {
            mInstance = new DataManager(context);
        }
    }

    public static DataManager getInstance(Context context) {
        if (mInstance == null) {
            createInstance(context);
        }
        return mInstance;
    } 

    public void setOnDataListener(OnDataListener dataListener){
        mDataListener = dataListener;
    }

    public void sentBC(){
        int index = mCount++;
        Log.e("xiri", "DataManager sentBC index = "+index);
        Runnable task = new Task(index);
        mActiveTask.put(index, task);

        mHandler.postDelayed(task, 1000);

        final Intent in = new Intent();
        in.setAction("ZJT_XIRI");
        in.putExtra(""+index, ""+index);
        in.putExtra("INDEX", index);
        //模拟广播超时
        if(mIsFirster){
            mIsFirster = false;
            new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {
                    mContext.sendBroadcast(in);
                }
            }, 2000);
        }else{
            mIsFirster = true;
            mContext.sendBroadcast(in);
        }

    }

    class Task implements Runnable{

        private int count;
        public Task(int cnt){
            count = cnt;
            Log.e("xiri", "Task :: count = "+count);
        }

        @Override
        public void run() {
            Log.e("xiri", "Task :: run 移除 任务 "+count);
            mActiveTask.remove(count);
            if(mDataListener != null){//超过1s,则返回一个空的数据
                mDataListener.onLoad(null);
            }
        }

    }

    interface OnDataListener {
        void onLoad(String data);
    }

}

这段代码很简单,都有注释,就不解释了。最后就是在Activity中注册DataManager的OnDataListener 回调,然后调用sentBC()来发送广播。

好啦,核心代码就这么多了。想表达的就是一种实现方式。有疑问的可以交流下。

猜你喜欢

转载自blog.csdn.net/zhujiangtaotaise/article/details/76228646