You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 05:53:18