Flutter集成原生Android时ActivityResultLauncher调用launch报空指针异常
问题根源
ActivityResultLauncher的初始化与调用依赖Activity级别的Context,你使用的ApplicationContext是全局上下文,不具备Activity的生命周期关联,调用launch时无法获取到Activity的上下文信息,从而触发空指针异常。
解决方案
1. 实现ActivityAware接口监听Activity生命周期
Flutter插件需要感知Activity的绑定与解绑,才能获取到可用的Activity实例。修改插件类,实现ActivityAware接口:
public class YourPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware { private MethodChannel channel; private Activity activity; private ActivityResultLauncher<String> mGetContent; private static final String CHANNEL = "your_plugin_channel"; @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), CHANNEL); channel.setMethodCallHandler(this); } @Override public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { activity = binding.getActivity(); // 此时Activity已绑定,在这里注册ActivityResultLauncher mGetContent = activity.registerForActivityResult(new ActivityResultContracts.GetContent(), uri -> { // 处理返回的Uri,可通过MethodChannel回调给Flutter if (uri != null) { channel.invokeMethod("imageSelected", uri.toString()); } }); } @Override public void onDetachedFromActivityForConfigChanges() { // 配置变更时解绑Activity,清理引用 activity = null; mGetContent = null; } @Override public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { // 配置变更后重新绑定Activity,重新注册Launcher onAttachedToActivity(binding); } @Override public void onDetachedFromActivity() { // 完全解绑Activity,清理引用 activity = null; mGetContent = null; } @Override public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { channel.setMethodCallHandler(null); channel = null; } @Override public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { if (call.method.equals("pickImage")) { pickImage(result); } else { result.notImplemented(); } } private void pickImage(Result result) { if (activity == null || mGetContent == null) { result.error("ACTIVITY_NULL", "Activity not available", null); return; } try { mGetContent.launch("image/*"); } catch (Exception e) { result.error("LAUNCH_ERROR", e.getLocalizedMessage(), null); } } }
2. 核心注意事项
- 禁止用ApplicationContext注册Launcher:
registerForActivityResult必须由Activity实例调用,它依赖Activity的生命周期管理结果回调,全局上下文无法提供这些能力。 - 处理Activity生命周期变更:当Activity因屏幕旋转等配置变更销毁重建时,需重新注册Launcher,否则会导致回调失效或空指针。
- 增加空值判断:调用
launch前必须检查Activity和Launcher是否不为空,避免在Activity未绑定的情况下触发操作。
3. 为什么ApplicationContext无效?
ApplicationContext是全局上下文,不持有当前Activity的实例,而ActivityResultContracts.GetContent本质是启动Activity选择图片,需要依赖当前Activity的栈和生命周期,ApplicationContext无法提供这些信息,因此调用launch时会抛出空指针异常。
内容的提问来源于stack exchange,提问作者ahmed elkhyary
相关产品推荐
相关产品推荐

