Android(安卓)不依赖于Activity的全局对话框Dialog
16lz
2021-01-26
正常初始化对话框的写法
一般的Dialog对象初始化都需要依赖于Activity,如下
new AlertDialog.Builder(activity) .setTitle("野猿新一") .setMessage("我是对话框内容啦") .show();
BroadcastReceiver如果是在Activity中注册的,用onReceive(Context context, Intent intent)方法的context参数来初始化Dialog是可以正常弹出对话框的。因为这里的context其实是一个Activity对象,如下所示:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (context instanceof Activity) { new AlertDialog.Builder(context) .setTitle("野猿新一") .setMessage("我是对话框内容啦") .show(); } } }, new IntentFilter("com.him.action")); }}
会报错的写法
虽说AlertDialog.Builder(Context context)的参数是Context,但是如果传入的是非Activity的Context,比如说Application,就会报如下所示的错误
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application at android.view.ViewRootImpl.setView(ViewRootImpl.java:700) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:289) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85) at android.app.Dialog.show(Dialog.java:298) at android.app.AlertDialog.show(AlertDialog.java:1128) at android.app.AlertDialog$Builder.show(AlertDialog.java:1008) at com.him.autosizingtest.MainActivity$1.onClick(MainActivity.java:21) at android.view.View.performClick(View.java:4918) at android.view.View$PerformClick.run(View.java:20399) at android.os.Handler.handleCallback(Handler.java:815) at android.os.Handler.dispatchMessage(Handler.java:104) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5869) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1019) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:814)
所以以下的几种写法都会报错
new AlertDialog.Builder(activity.getApplication()) .setTitle("野猿新一") .setMessage("我是对话框内容啦") .show();new AlertDialog.Builder(activity.getApplicationContext()) .setTitle("野猿新一") .setMessage("我是对话框内容啦") .show();
BroadcastReceiver如果是在Manifest中声明的,用onReceive(Context context, Intent intent)方法的context参数来初始化Dialog,一样还会报Unable to add window -- token null is not for an application错误。所以如下写法也不可行
public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { new AlertDialog.Builder(context) .setTitle("野猿新一") .setMessage("我是对话框内容啦") .show(); }}// 在manifest中声明
全局Dialog
但是如果说有些情况下获取不到Activity对象,但是又想弹出Dialog呢?这时候用全局的Dialog是可以实现的。
只需要设置dialog为WindowManager.LayoutParams.TYPE_SYSTEM_ALERT类型
然后添加android.permission.SYSTEM_ALERT_WINDOW权限
Dialog dialog = new AlertDialog.Builder(activity.getApplicationContext()) .setTitle("野猿新一") .setMessage("我是对话框内容啦") .create();// 增加这句代码dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);dialog.show();// 然后在manifest中添加权限
更多相关文章
- Android(安卓)Studio 之 对话框开发(Dialog) ---- 两种方式来实
- 解决-Android: 跨应用AIDL调用时报错 java.lang.SecurityExcepti
- [android常见错误]Export aborted because fatal lint errors we
- 详解Android中Dialog的使用
- (4.1.14)Android使用Activity用作弹出式对话框
- @suppresslint 标注忽略指定的警告(HandlerLeak)
- android java.lang.NoSuchFieldError: R$id.xxx
- Android(安卓)AlertDialog 方法setView(view,0,0,0,0)开发自定义
- Android自定义Dialog二次调用报错解决方法:The specified child a