Dialog style Activity + SingleTask 被踢弹窗下线退出至登录界面

Dialog 依附于 Acitivity .
非Activity的context 或者 全局监听中

常规new dialog的方式调不起弹窗

exitDialog = new Dialog(context, R.style.loading_dialog);
exitDialog.setCancelable(false);
View view = LayoutInflater.from(context).inflate(R.layout.dialog, null);
TextView tv = (TextView) view.findViewById(R.id.popubwindow_ok_content_tv);
if (!StringUtil.isEmpty(tips)) {
tv.setText(tips);
} else {
tv.setText(context.getResources().getString(R.string.str_exit_content));
}
exitDialog.setContentView(view);
view.findViewById(R.id.popubwindow_ok_ok_tv).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
XwgUtils.exist2login(context);
dismissExitDialog();
}
});
exitDialog.setOnDismissListener(new OnDismissListener() {

@Override
public void onDismiss(DialogInterface dialog) {
dismissExitDialog();
}
});

增加以下部分

exitDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />  

部分手机(小米)仍弹不出来,需要给予显示悬浮窗的权限

解决思路:使用 Dialog样式的Activity 

通过跳转+SingleTask 实现被踢下线提示退出至登录界面

public class ExistDialogActivity extends Activity {

    public static final String KEY_EXIST_APP = "exist";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_exist_activity);
        ((TextView) findViewById(R.id.title)).setText(R.string.str_exit_title);
        ((TextView) findViewById(R.id.content)).setText(R.string.str_exit_content);
        ((TextView) findViewById(R.id.confirm)).setText("确 定");

        findViewById(R.id.confirm).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                exist();
            }
        });
    }

    private void exist() {
        Intent intent = new Intent(ExistDialogActivity.this, MainActivity.class);
        intent.putExtra(KEY_EXIST_APP, true);
        startActivity(intent);
        finish();
    }

    @Override
    public void onBackPressed() {
    }
}

AndroidManifest中

 <activity
            android:name=".ui.other.ExistDialogActivity"
            android:configChanges="orientation|keyboardHidden"
            android:launchMode="singleTask"
            android:screenOrientation="portrait"
            android:theme="@style/existDialogStyle"
            android:windowSoftInputMode="stateHidden" />

styles文件中

<style name="existDialogStyle">
        <item name="android:windowBackground">@android:color/transparent</item>
        <!--设置Dialog的windowFrame框为无-->
        <item name="android:windowFrame">@null</item>
        <!--设置无标题-->
        <item name="android:windowNoTitle">true</item>
        <!--是否浮现在activity之上-->
        <item name="android:windowIsFloating">true</item>
        <!--是否半透明-->
        <item name="android:windowIsTranslucent">true</item>
        <!--设置窗口内容不覆盖-->
        <item name="android:windowContentOverlay">@null</item>
        <!--设置动画,在这里使用让它继承系统的Animation.Dialog-->
        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
        <!--背景是否模糊显示-->
        <item name="android:backgroundDimEnabled">true</item>
        <!--点击对话框外部不消失-->
        <item name="android:windowCloseOnTouchOutside">false</item>

        <item name="android:textSize">14sp</item>
        <item name="android:textStyle">normal</item>
        <item name="android:textColor">@android:color/black</item>
    </style>

最后三行item增加的原因。是我遇到了奇怪的现象

我的小米note3死活不显示layout中textview的文字内容,就是白白一片。增加后上述三行配置才显示出内容来

xml布局文件的设置才起效果,不知什么原因。

我的xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/shape_cicle_white"
    android:orientation="vertical">

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:gravity="center_vertical|left"
        android:paddingLeft="12dp"
        android:text="@string/str_exit_title"
        android:textColor="@color/code_green"
        android:textSize="16sp"
        android:textStyle="normal" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@drawable/separator_line" />

    <TextView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="52dp"
        android:gravity="center_vertical|left"
        android:paddingLeft="12dp"
        android:text="@string/str_exit_content"
        android:textSize="16sp" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@drawable/separator_line" />

    <TextView
        android:id="@+id/confirm"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:clickable="true"
        android:gravity="center"
        android:text="@string/str_ok"
        android:textSize="16sp" />
</LinearLayout>

另外注意 style如果是这样的

<style name="existDialogStyle" parent="Theme.AppCompat.Dialog">

那么对应的Activity extends 的

public class ExistDialogActivity extends AppCompatActivity

如果style 非 AppCompat 则extends Activity 

否则会报类似错

java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

还有要注意的是 调用起 该Dialog Acitivity 的方式

   startActivity(new Intent(context, ExistDialogActivity.class)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));

addFlags FLAG_ACTIVITY_NEW_TASK

因为非Acitivity的context调用时如果栈中无该类,会报错

Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
点击打开链接

FLAG_ACTIVITY_NEW_TASK:例如现在栈1的情况是:A B C。C通过intent跳转到D,并且这个intent添加了FLAG_ACTIVITY_NEW_TASK标记,如果D这个Activity在Manifest.xml中的声明中添加了Task affinity,系统首先会查找有没有和D的Task affinity相同的task栈存在,如果有存在,将D压入那个栈,如果不存在则会新建一个D的affinity的栈将其压入。如果D的Task affinity默认没有设置,则会把其压入栈1,变成:A B C D,这样就和不加FLAG_ACTIVITY_NEW_TASK标记效果是一样的了。注意如果试图从非activity的非正常途径启动一个activity(例见下文“intent.setFlags()方法中参数的用例”),比如从一个service中启动一个activity,则intent比如要添加FLAG_ACTIVITY_NEW_TASK标记(编者按:activity要存在于activity的栈中,而非activity的途径启动activity时必然不存在一个activity的栈,所以要新起一个栈装入启动的activity)。简而言之,跳转到的activity根据情况,可能压在一个新建的栈中。

直到此时,我们的dialog样式的acitivity应该能正常显示出来了

然后我们运用SingleTask 和 onNewIntent 方法实现清除所有非相关activity

onNewIntent 的使用场景

launchMode为singleTask的时候,通过Intent跳到一个Activity,如果系统已经存在一个实例,系统就会将请求发送到这个实例上,但这个时候----------系统就不会再调用onCreate方法,而是调用onNewIntent方法。

我们在MainActivity 的 onNewIntent 方法中做处理,当然MainActivity 的LaunchMode 是 SingleTask

 @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (intent != null) {
            boolean isExistApp = intent.getBooleanExtra(ExistDialogActivity.KEY_EXIST_APP, false);
            if (isExistApp) {
                startActivity(new Intent(this, LoginActivity.class));
                finish();
                return;
            }
        .............
        }
    }
至此,我们完成了从非activity 或全局监听下 弹出下线弹窗 并 完成清退所有activity 并跳转回登录界面的功能。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值