Flutter插件中ActivityPluginBinding返回null,AlertDialog无法显示求助
问题描述
在Flutter插件中调用AlertDialog必须依赖Activity上下文,使用Application上下文会触发如下错误:
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
但实现ActivityAware接口后,调用getActivity()始终返回null,相关实现代码如下:
public class MyPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware { private ActivityPluginBinding activityBinding; private FlutterPluginBinding flutterBinding; @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { flutterBinding = flutterPluginBinding; } @Override public void onAttachedToActivity(ActivityPluginBinding binding) { activityBinding = binding; } @Override public void onDetachedFromActivity() { activityBinding = null; } @Override public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) { activityBinding = binding; } @Override public void onDetachedFromActivityForConfigChanges() { activityBinding = null; } // Implementation public Context getApplicationContext() { return (flutterBinding != null) ? flutterBinding.getApplicationContext() : null; } public Activity getActivity() { return (activityBinding != null) ? activityBinding.getActivity() : null; } }
排查方向与解决办法
1. 未正确注册MethodChannel
如果onAttachedToEngine中未完成MethodChannel的注册,或注册时未传入当前插件实例作为处理器,会导致方法调用时插件未与引擎正确关联,此时可能还未触发onAttachedToActivity回调,getActivity()自然返回null。
修正代码:
@Override public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { flutterBinding = flutterPluginBinding; // 注册MethodChannel并绑定当前实例作为handler new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "your_plugin_channel_id") .setMethodCallHandler(this); }
2. 方法调用时机过早
如果在onAttachedToActivity回调触发前就调用了依赖Activity的方法,此时activityBinding还未被赋值,会返回null。比如插件刚初始化就触发AlertDialog调用。
解决方式:
- 在调用AlertDialog前先判断
getActivity()是否为null,若为null可延迟执行或提示用户稍后操作; - 可在
onAttachedToActivity回调中缓存Activity实例,同时触发等待中的任务。
3. 插件注册方式错误
若插件通过AndroidManifest.xml静态注册,而非动态注册,ActivityAware的生命周期回调可能无法被正确触发。Flutter插件推荐动态注册以保证回调正常执行。
确认注册逻辑:在MainActivity的configureFlutterEngine方法中注册插件:
@Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { super.configureFlutterEngine(flutterEngine); flutterEngine.getPlugins().add(new MyPlugin()); }
4. 配置变更时的绑定丢失
设备发生配置变更(如屏幕旋转)时,会触发onDetachedFromActivityForConfigChanges,之后需要onReattachedToActivityForConfigChanges重新绑定Activity。若此时插件未重新获取Activity实例,调用时会返回null。
你的代码中已实现onReattachedToActivityForConfigChanges的绑定逻辑,但需注意配置变更后调用方法时,要重新通过getActivity()获取实例。
5. 插件实例重复创建
若插件被多次实例化,可能导致持有activityBinding的实例并非当前活跃实例,调用getActivity()时拿到旧实例的null值。
解决方式:
- 确保插件以单例方式注册;
- 在
onDetachedFromEngine中清理资源并注销MethodChannel:
@Override public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { flutterBinding = null; new MethodChannel(binding.getBinaryMessenger(), "your_plugin_channel_id") .setMethodCallHandler(null); }
内容的提问来源于stack exchange,提问作者Kyle Lynch

