mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-07-26 05:51:18 +02:00
fix(android): stop double-destroying the shared audio_service engine
MainActivity only overrode provideFlutterEngine, so the activity's fragment delegate treated the plugin-cached engine as its own (createFlutterFragment forwards shouldDestroyEngineWithHost, default true) and destroyed it when the activity finished, while the engine stayed registered in AudioServicePlugin's FlutterEngineCache. When AudioService stopped afterwards, disposeFlutterEngine() called destroy() on the already destroyed engine and crashed the app with "Cannot execute operation because FlutterJNI is not attached to native". Mirror audio_service's own AudioServiceFragmentActivity: expose the plugin engine as a cached engine (getCachedEngineId), never destroy it with the host (shouldDestroyEngineWithHost = false), and pre-create it in onCreate. The plugin remains the engine's sole owner and disposes it only once, when the service stops with no activity attached.
This commit is contained in:
@@ -38,10 +38,24 @@ import java.security.MessageDigest
|
||||
import java.util.Locale
|
||||
|
||||
class MainActivity: FlutterFragmentActivity() {
|
||||
// Mirrors audio_service's AudioServiceFragmentActivity: the shared engine
|
||||
// is owned by AudioServicePlugin's FlutterEngineCache. Without the
|
||||
// cached-engine-id + shouldDestroyEngineWithHost overrides, the activity
|
||||
// (via createFlutterFragment's destroyEngineWithFragment) destroys the
|
||||
// provided engine on exit while it stays registered in the cache; when
|
||||
// AudioService later stops, disposeFlutterEngine() destroys it a second
|
||||
// time and crashes with "FlutterJNI is not attached to native".
|
||||
override fun provideFlutterEngine(context: Context): FlutterEngine {
|
||||
return AudioServicePlugin.getFlutterEngine(context)
|
||||
}
|
||||
|
||||
override fun getCachedEngineId(): String {
|
||||
AudioServicePlugin.getFlutterEngine(this)
|
||||
return AudioServicePlugin.getFlutterEngineId()
|
||||
}
|
||||
|
||||
override fun shouldDestroyEngineWithHost(): Boolean = false
|
||||
|
||||
private val CHANNEL = "com.zarz.spotiflac/backend"
|
||||
private val DOWNLOAD_PROGRESS_STREAM_CHANNEL =
|
||||
"com.zarz.spotiflac/download_progress_stream"
|
||||
@@ -2060,6 +2074,9 @@ class MainActivity: FlutterFragmentActivity() {
|
||||
override fun shouldHandleDeeplinking(): Boolean = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
// Ensure the shared audio_service engine exists before the activity
|
||||
// delegate looks it up by cached id (see getCachedEngineId above).
|
||||
AudioServicePlugin.getFlutterEngine(this)
|
||||
super.onCreate(savedInstanceState)
|
||||
handleExtensionOAuthIntent(intent)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user