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

本文介绍了一种在Android应用中实现在任意时刻展示全局对话框的方法。通过在Application中保存当前Activity,并在需要显示对话框时调用特定方法,确保对话框始终出现在最上层。文章还讨论了多窗口支持下的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果我们的app支持单点登录、账户踢出功能,那么在接到后端push的“需要踢出当前用户”的消息后就需要弹出一个dialog。这种dialog出现的时机并不确定,一种方式就是做一个系统层面的dialog,就像ANR时出现的系统dialog,让其永远保持在屏幕的上方。

Dialog dialog = new Dialog(this);
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.show();
复制代码

但这种写法有两个问题,一个是TYPE_SYSTEM_ALERT已经被废弃,其二是需要增加权限。

/** @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对象:

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的方法:

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()来完成弹窗:

((App) getApplication()).showDialog("全局弹窗", "可在任意时机弹出一个dialog")
复制代码

这里的代码在onResume()onPause()做了activity对象的获取,可以保证获取的是当前最上层的activity,当app退出到后台后这个curActivity会变为null,不允许弹出对话框了。最后记得要在弹出时做个activity的判空或isDestroyed()之类的判断,防止使用了即将销毁的activity。

题外话:

当你的应用支持了分屏功能,也就是多窗口后,那么则需要在onStop()中清空activity,在onStart()中得到activity,更多详细内容请参考《多窗口支持  |  Android Developers》

@Override
public void onActivityStarted(Activity activity) {
    curActivity = (AppCompatActivity) activity;
}

@Override
public void onActivityStopped(Activity activity) {
    curActivity = null;
}
复制代码

联系作者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值