Flutter Android插件onDestroy无法读取初始化变量问题排查
问题分析与解决方案
核心原因
你的插件类同时继承了MediaBrowserService并实现了FlutterPlugin接口,但这两个组件的实例完全独立:
onAttachedToEngine是Flutter引擎初始化插件时调用的,对应的是FlutterPlugin实例,你在initInstance中初始化的变量都属于这个实例;onDestroy是Android系统销毁MediaBrowserService服务实例时触发的,这个服务实例和FlutterPlugin实例不是同一个对象,所以你看到的都是类的初始默认值(randomString为"lowercase",其他变量为null)。
对疑问的解答
onDestroy确实可能运行在单独的进程中(如果你的MediaBrowserService在Manifest里配置了android:process属性),即使没有配置多进程,服务实例和FlutterPlugin实例也是两个完全不同的对象,所以父类显示插件类名是正常的,但两者的状态完全不共享。
修复方案
1. 拆分独立组件(推荐)
将FlutterPlugin和MediaBrowserService拆分为两个独立的类:
- 一个类专门实现
FlutterPlugin和MethodCallHandler,负责和Flutter端通信; - 另一个类单独继承
MediaBrowserService,负责音频服务的生命周期和逻辑; - 两者通过
EventChannel、Binder或者本地广播来传递状态和指令,确保服务实例能获取到Flutter侧传递的必要数据。
2. 共享状态(临时方案)
如果必须保留在同一个类中,可以将需要跨实例共享的变量改为静态变量,或者实现单例模式确保只有一个实例被创建:
public class FlutterPlugin extends MediaBrowserService implements FlutterPlugin, MethodCallHandler { private static String randomString = "lowercase"; private static MethodChannel channel; private static AudioManager am; private static Context mContext; // ... 其他静态变量 private void initInstance(BinaryMessenger binaryMessenger, Context context) { channel = new MethodChannel(binaryMessenger, ID); channel.setMethodCallHandler(this); am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); mContext = context; // ... 其他初始化逻辑 randomString = "UPPERCASE"; } @Override public void onDestroy() { // 此时可以访问到静态变量的正确值 Log.d(TAG, randomString); // 输出 "UPPERCASE" // ... 清理逻辑 } }
注意:静态变量可能导致内存泄漏,使用时需要谨慎处理,确保在合适的时机释放资源。
3. 修正代码拼写错误
你的代码中存在拼写错误:this.randomStirng = "UPPERCASE"应该改为this.randomString = "UPPERCASE",这个错误也会导致randomString始终保持初始值。
内容的提问来源于stack exchange,提问作者Kaki Master Of Time
相关产品推荐
相关产品推荐

