线程切换那点事,Application全局弹出自定义DIalog

1.前言:最近忙于写项目,也没时间去更新博客了,下面要说的是,也是比较常见的一个问题!
需求:当后台推送一条消息过来的时候如果类型为99,则全局弹出一个DIalog 提示账号在别处登录
其实网上有好多案例,但我试了一下发现还是不行,这时候就涉及到一个线程切换问题。


2.首先看下效果图:
线程切换那点事,Application全局弹出自定义DIalog_第1张图片
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 性能优化最佳实践,详细请点击

你可能感兴趣的:(android)