完美实现帐户踢出时的全局弹窗

若是咱们的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;
}
复制代码

联系做者

相关文章
相关标签/搜索