完美實現帳戶踢出時的全局彈窗

若是咱們的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;
}
複製代碼

聯繫做者

相關文章
相關標籤/搜索