1.前言:最近忙于写项目,也没时间去更新博客了,下面要说的是,也是比较常见的一个问题!
需求:当后台推送一条消息过来的时候如果类型为99,则全局弹出一个DIalog 提示账号在别处登录
其实网上有好多案例,但我试了一下发现还是不行,这时候就涉及到一个线程切换问题。
2.首先看下效果图:
3.下面看下实现代码:
//全局弹框
public static void showAllDialog(Activity context, String title) {
if (context == null) {
return;
}
// if (Looper.getMainLooper() == Looper.myLooper()) {
// Log.e("TAS", "主线程");
// } else {
// Log.e("TAS", "不是主线程(子线程)");
// }
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
//此时已在主线程中,可以更新UI了
View mView = LayoutInflater.from(context).inflate(R.layout.layout_verify_item, null);
LinearLayout linCancel = (LinearLayout) mView.findViewById(R.id.linCancel);
LinearLayout linAll = (LinearLayout) mView.findViewById(R.id.linAll);
TextView tvTitle = (TextView) mView.findViewById(R.id.tvTitle);
tvTitle.setText(title);
Dialog dialog = new Dialog(context);
dialog.setContentView(mView);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
if (!dialog.isShowing()) {
dialog.show();
}
DisplayMetrics dm = context.getResources().getDisplayMetrics();
int displayWidth = dm.widthPixels;
int displayHeight = dm.heightPixels;
android.view.WindowManager.LayoutParams p = dialog.getWindow().getAttributes(); //获取对话框当前的参数值
p.width = (int) (displayWidth * 0.8); //宽度设置为屏幕的0.5
p.height = (int) (displayHeight * 0.35); //高度设置为屏幕的0.5
dialog.setCanceledOnTouchOutside(false);// 设置点击屏幕Dialog不消失
dialog.setCancelable(false);
dialog.getWindow().setAttributes(p); //设置生效
linAll.setOnClickListener(v -> {
dialog.dismiss();
Intent intent = new Intent(getAppContext(), LoginActivity.class);
context.startActivity(intent);
PreferencesUtil.putString(getAppContext(), "userId", "");
PreferencesUtil.putString(getAppContext(), "token", "");
PreferencesUtil.putString(getAppContext(), "userToken", "");
MyApplication.finishAllActivity();//清空所有activity
MobclickAgent.onProfileSignOff();
});
}
});
}
4.如上代码就是一个自定义dialog,我们先看下:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
这句代码,也是网上比较多的写法。大概意思是:通过修改Dialog中window的type属性以及增加层叠窗口的权限实现弹窗,当然我试了一下并没有什么效果。
5.看下调用地方:
public void getNotification(String msg) {
MessageContent message = new Gson().fromJson(msg, MessageContent.class);
int action = message.getAction();
int key = message.getKey();
// 点击的意图ACTION是跳转到Intent
if (action == 1 && key == 1) {
//其他设备在其他地方登录
showAllDialog(MyApplication.getTopActivity(), "您的设备已在别处登录");
}
}
/**
* @return 作用说明 :获取当前最顶部activity的实例
*/
public static Activity getTopActivity() {
Activity mBaseActivity = null;
synchronized (mActivitys) {
final int size = mActivitys.size() - 1;
if (size < 0) {
return null;
}
mBaseActivity = mActivitys.get(size);
}
return mBaseActivity;
}
6.最后尼,代码贴完了。下面我就来给大家说下实现的思路:
第一:如果非要在子线程中实现Dialog.show(); 怎么啵?
很简单线程切换呗:
//请注意,这行代码是关键代码
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
//此时已在主线程中,可以更新UI了
}
});
第二:getTopActivity()这个方法是为了获取到当前显示的Activity,也就是栈顶的Activity,这时候是不能用Context会有问题的。 以上尼就分享这么多,有不懂的地方可留言,写的不好的地方希望大家多多包涵,勿喷 谢谢。
最后分享一篇文章,我也是掘金上看到的:
Android 性能优化最佳实践,详细请点击