若是咱们的app支持单点登陆、帐户踢出功能,那么在接到后端push的“须要踢出当前用户”的消息后就须要弹出一个dialog。这种dialog出现的时机并不肯定,一种方式就是作一个系统层面的dialog,就像ANR时出现的系统dialog,让其永远保持在屏幕的上方。java
Dialog dialog = new Dialog(this);
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.show();
复制代码
但这种写法有两个问题,一个是TYPE_SYSTEM_ALERT
已经被废弃,其二是须要增长权限。android
/** @deprecated */
@Deprecated
public static final int TYPE_SYSTEM_ALERT = 2003;
复制代码
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
复制代码
咱们能够换个思路来考虑这个需求,要知道dialog的构建和activity是强相关的,解决方案是永远保存当前的activity对象,当锁屏和app退出到后台时,清空保存的当前activity。后端
首先,在application中持有当前的activity对象:bash
public class App extends Application {
private AppCompatActivity curActivity;
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityResumed(Activity activity) {
curActivity = (AppCompatActivity) activity;
}
@Override
public void onActivityPaused(Activity activity) {
curActivity = null;
}
});
}
}
复制代码
而后,定义弹出dialog的方法:app
public class App extends Application {
private AppCompatActivity curActivity;
public void showDialog(String title, String message) {
if (curActivity == null) {
return; // 不要忘了判空操做
}
EasyDialog.builder(curActivity)
.setTitle(title)
.setMessage(message)
.setPositiveButton("ok", null)
.build()
.show(curActivity.getSupportFragmentManager());
}
}
复制代码
最后,在须要的时候调用application中的showDialog()来完成弹窗:ide
((App) getApplication()).showDialog("全局弹窗", "可在任意时机弹出一个dialog")
复制代码
这里的代码在onResume()
和onPause()
作了activity对象的获取,能够保证获取的是当前最上层的activity,当app退出到后台后这个curActivity
会变为null,不容许弹出对话框了。最后记得要在弹出时作个activity的判空或isDestroyed()之类的判断,防止使用了即将销毁的activity。ui
题外话:this
当你的应用支持了分屏功能,也就是多窗口后,那么则须要在onStop()中清空activity,在onStart()中获得activity,更多详细内容请参考《多窗口支持 | Android Developers》。spa
@Override
public void onActivityStarted(Activity activity) {
curActivity = (AppCompatActivity) activity;
}
@Override
public void onActivityStopped(Activity activity) {
curActivity = null;
}
复制代码