1.背景
在项目中遇到一个这样的需求:当服务器发来请求弹窗信号后,要在当前界面弹出一个对话框。
2.遇到的问题
1)重复弹窗
做法:
定义1个BaseActivity,然后所有的Activity都继承于BaseActivity,当收到服务器请求弹窗信号后,发送请求弹出对话框的广播;然后在BaseActivity中注册该条广播,并在广播接收器的onReceive()方法中去弹出对话框
问题现象:重复弹窗
当由AActivity跳转到BActivity后,此时发出请求弹出广播,这时BActivity会弹出对话框,返回到AActivity后,会再次弹窗。
2)无法弹出,系统奔溃
做法:
由于BaseActivity的做法会导致重复弹窗,分析到是由于广播接收器重复注册导致的,因此想采用广播静态注册的方式,结果在创建的广播类中,无法弹窗,系统奔溃
3.需求最终解决方案
在每一个需要弹窗的Activity中去注册该条广播,然后Activity的内部类广播接收器中去处理:1)判断当前Activity是否在界面显示,2)如果在界面显示,则弹窗
具体代码
- 1.MyApplication中发送广播
//发送广播
Intent intent = new Intent();
intent.setAction("com.craneapp.testRequest");
sendBroadcast(intent);
- 2.Activity的onCreate()中注册广播
//注册广播
TestRequestReceiver requestReceiver = new TestRequestReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.craneapp.testRequest");
registerReceiver(requestReceiver,intentFilter);
- 3.Activity中的内部广播
//Activity中的内部广播
class TestRequestReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() == "com.craneapp.testRequest")
{
//当前Activity是否正在显示
boolean isTopActivity = CommonUtil.isForeground(application,MainActivity.class.getName());
if (isTopActivity)
{
//弹出对话框
CommonUtil.showTestDialog(application,MainActivity.this);
}
}
}
}
- 工具类中判断当前Activity是否在界面上显示
/**
* 判断某个界面是否在前台
*
* @param context Activity的getAppliction()获取
* @param className Activity名称 由类名.class.getName()获取
*
*/
public static boolean isForeground(Context context, String className) {
if (context == null || TextUtils.isEmpty(className)) {
return false;
}
ActivityManager am =(ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> list = am.getRunningTasks(1);
if (list != null && list.size() > 0) {
ComponentName cpn = list.get(0).topActivity;
if (className.equals(cpn.getClassName())) {
return true;
}
}
return false;
}