+-
Android中的消息提示无非就那几种,弹个窗(Toast或SnackBar),或者是弹出个对话框(Dialog),最近在使用的时候也是遇到了问题,有时候导致APP闪退
稍微研究会,总结了一下使用过程中需要注意的几个坑
需要切换到UI主线程
无论是使用弹窗或是弹个对话框,都需要在UI主线程中进行,否则就会导致APP闪退,由于自己经常是直接开个子线程进行网络请求的操作,偶尔会忘记切换回UI线程,就会导致闪退,提醒自己注意一下
自己封装了个弹窗方法作为BaseActivity一个方法中,这样之后新写的Activity页面都是继承这个BaseActivity,需要弹窗,调用方法很方便,连context也可以不用传,十分舒服
需要注意的是,封装记得在外层套个切换主线程的方法,如:
private void showToast(final String msg) { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } }); }
切换UI主线程的方法详情进参考Android开发——实现子线程更新UI - Stars-one - 博客园
后台Service弹窗
首先,得声明一个悬浮窗权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
使用了后台服务,但需要弹个窗,可以使用下面的代码
Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { @Override public void run() { AlertDialog dialog = new AlertDialog.Builder(BaseMsgService.this) .setTitle("提示").setMessage(str).setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }).create(); dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); dialog.show(); } });
悬浮窗权限
悬浮窗权限这单主要是针对的对话框,由于Android6.0引入了动态权限,如果从开启了一个Service,弹出对话框也会导致APP闪退,错误提示为:
permission denied for window type 2003
如下图所示
可能你的报错提示不是上面这个,但是有
permission denied这两个字样,估计就是权限的问题
处理的方式很简单,只需要授权即可
//6.0以上需要获取弹窗权限,跳转到设置页面 if (Build.VERSION.SDK_INT >= 23) { if (!Settings.canDrawOverlays(Login.this)) { Toast.makeText(Login.this, "软件需要悬浮窗权限,跳转到设置页面请手动勾选允许", Toast.LENGTH_SHORT).show(); new Thread(new Runnable() { @Override public void run() { runOnUiThread(new Runnable() { @Override public void run() { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); startActivityForResult(intent, 111); } }); } }).start(); } }