简体   繁体   中英

Requested flutter engine does not exist in Add to app

I have flutter into the existing native app (Add to app) with a cached flutter engine.

override fun onCreate(savedInstanceState: Bundle?) {
        Log.d(TAG, "onCreate")
        
        
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)
        context = this.application.applicationContext
        if (!FlutterEngineCache.getInstance().contains(
                FLUTTER_ENGINE
            )
        ) {
            mFlutterEngine = FlutterEngine(context)
            mFlutterEngine.dartExecutor
                .executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault())
            FlutterEngineCache.getInstance()
                .put(FLUTTER_ENGINE, mFlutterEngine)
        }
        //Create Flutter Fragment
        mFragmentManager = supportFragmentManager
        mFlutterFragment = mFragmentManager.findFragmentByTag(FLUTTER_FRAGMENT) as FlutterFragment?
        if (mFlutterFragment == null) {
            mFlutterFragment =
                FlutterFragment.withCachedEngine(FLUTTER_ENGINE).transparencyMode(FlutterView.TransparencyMode.opaque).build()
            mFragmentManager
                .beginTransaction()
                .add(R.id.fragment_container, mFlutterFragment as Fragment, FLUTTER_FRAGMENT)
                .commit()
        } else {
            mFragmentManager
                .beginTransaction()
                .show(mFragmentManager.findFragmentByTag(FLUTTER_FRAGMENT)!!)
                .commit()
        }
}

I am getting the following crash in the production app

  Caused by: java.lang.IllegalStateException: The requested cached FlutterEngine did not exist in the FlutterEngineCache: 'FLUTTER_ENGINE'
        at io.flutter.embedding.android.FlutterActivityAndFragmentDelegate.setupFlutterEngine(FlutterActivityAndFragmentDelegate.java:211)
        at io.flutter.embedding.android.FlutterActivityAndFragmentDelegate.onAttach(FlutterActivityAndFragmentDelegate.java:157)
        at io.flutter.embedding.android.FlutterFragment.onAttach(FlutterFragment.java:597)
        at androidx.fragment.app.Fragment.performAttach(Fragment.java:2574)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:828)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2659)
        at androidx.fragment.app.FragmentManagerImpl.dispatchCreate(FragmentManagerImpl.java:2607)
        at androidx.fragment.app.FragmentController.dispatchCreate(FragmentController.java:235)
        at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:316)
        at androidx.appcompat.app.AppCompatActivity.onCreate(AppCompatActivity.java:106)
        at com.flutter.android.MainActivity.onCreate(MainActivity.kt:33)
 

How to reproduce

  1. Open developer settings, set "Background processes" to "No Background Processes" and set on the Don't keep activities.

  2. Open the app press and home

  3. Open the app again.. it will crash with the exception.

    Caused by: java.lang.IllegalStateException: The requested cached FlutterEngine did not exist in the FlutterEngineCache: 'FLUTTER_ENGINE'

Solution

initialize the flutter engine before super.oncreate()

override fun onCreate(savedInstanceState: Bundle?) {
        Log.d(TAG, "onCreate")
         context = this.application.applicationContext
        if (!FlutterEngineCache.getInstance().contains(
                FLUTTER_ENGINE
            )
        ) {
            mFlutterEngine = FlutterEngine(context)
            mFlutterEngine.dartExecutor
                .executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault())
            FlutterEngineCache.getInstance()
                .put(FLUTTER_ENGINE, mFlutterEngine)
        }
       
        
        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)
        //Create Flutter Fragment
        mFragmentManager = supportFragmentManager
        mFlutterFragment = mFragmentManager.findFragmentByTag(FLUTTER_FRAGMENT) as FlutterFragment?
        if (mFlutterFragment == null) {
            mFlutterFragment =
                FlutterFragment.withCachedEngine(FLUTTER_ENGINE).transparencyMode(FlutterView.TransparencyMode.opaque).build()
            mFragmentManager
                .beginTransaction()
                .add(R.id.fragment_container, mFlutterFragment as Fragment, FLUTTER_FRAGMENT)
                .commit()
        } else {
            mFragmentManager
                .beginTransaction()
                .show(mFragmentManager.findFragmentByTag(FLUTTER_FRAGMENT)!!)
                .commit()
        }

I think the problem here is that when OS auto kills activity, then all cache engines be killed, and when you re-open your app, you must control which engineId your flutter activity needs.

Example:

  • Your app have 2 activities: home (cache engineId0 ) => details (cache engineId1 ), and you put your engine name in ascending order (engineId1, engineId2, engineId3...). When you're on details page, you put your app into the background and use other apps, then sometimes OS auto kill your activity.
  • When you go back to your app, it will open details page (and of course go onCreate again), but the problem here is all engines be killed, then you check engine does not exist and your re-create engineId0 (the first in your stack engines), then your code using this engine, but seem savedInstanceState at super.onCreate still remembers and requests engineId1 at this details page => that cause the issue.

Solution:

  • You have to find out a way to name your engine instead of in ascending order.
  • Passing null to super.onCreate like this super.onCreate(null) then it won't request engineId1 like my example above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM