前言:今天接到一个需求:就是在发出广播后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()来发送广播。
好啦,核心代码就这么多了。想表达的就是一种实现方式。有疑问的可以交流下。