Невозможно предварительно прогреть двигатель и использовать его позже на Android

У меня есть SDK для Android, который будет использоваться клиентами, в SDK есть некоторые абстракции, поэтому клиентам не нужно иметь дело с привязками флаттера.

В SDK у меня есть что-то вроде этого


class SDKPrivate  {
private static FlutterEngine flutterEngine;
...
 public void initFlutterEngine(Context context){
        if(SDKPrivate.flutterEngine != null) return;

        SDKPrivate.flutterEngine = new FlutterEngine(context);

        SDKPrivate.flutterEngine.getDartExecutor()
                .executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault());
    }

    MyFragment createFragment() {
        return new MyFragment();
    }
...
}

Класс фрагмента

public class MyFragment extends FlutterFragment {

    @Override
    public boolean shouldAttachEngineToActivity() {
        return true;
    }

     @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated( savedInstanceState);
        GeneratedPluginRegistrant.registerWith(sdkPrivate.getEngine());
    }

    @Override
    @Nullable
    public FlutterEngine provideFlutterEngine(@NonNull Context context) {
        return sdkPrivate.getEngine();
    }

В примере приложения, которое я создал для проведения тестов, у меня есть основное действие, которое

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SDKPrivate.initFlutterEngine(getApplicationContext());

и у него есть кнопка, которая вызывает новое действие, внутри которого будет MyFragment.

Intent activity2Intent = new Intent(getApplicationContext(), FragActivity.class);
            startActivity(activity2Intent);

FragActivity похож на это

public class FragActivity extends AppCompatActivity  {

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_frag);

       MyFragment  frag = SDKPrivate.createFragment();

        getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.frame_layout, frag,  BuildConfig.APPLICATION_ID + ".MyFragment")
                .commit();
    }
}

Когда у меня есть такой код, когда я вхожу в FragActivity, приложение остается пустым. Но если я запускаю движок внутри FragActivity, приложение работает должным образом.

Как это, нормально

public class FragActivity extends AppCompatActivity  {

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_frag);
        SDKPrivate.initFlutterEngine(getApplicationContext());
       //Same code as showed above 
      ...
}

Есть причина для этого? Я также хочу дать клиенту возможность разогреть движок, а затем использовать его во фрагменте и в действии, не создавая новый.

трепещущий доктор -v

[✓] Flutter (Channel stable, v1.12.13+hotfix.5, on Mac OS X 10.15.1 19B2093, locale en-PT)
    • Flutter version 1.12.13+hotfix.5 at /Users/manuelpeixoto/flutter
    • Framework revision 27321ebbad (6 weeks ago), 2019-12-10 18:15:01 -0800
    • Engine revision 2994f7e1e6
    • Dart version 2.7.0


[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /Users/manuelpeixoto/Library/Android/sdk/
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-29, build-tools 29.0.2
    • ANDROID_HOME = /Users/manuelpeixoto/Library/Android/sdk/
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 11.2.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.2.1, Build version 11B500
    • CocoaPods version 1.8.4

[✓] Android Studio (version 3.5)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 42.0.1
    • Dart plugin version 191.8593
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)

[✓] VS Code (version 1.41.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.7.1

[✓] Connected device (2 available)
    • XT1097                   • 0016256677                • android-arm • Android 6.0 (API 23)
    • iPhone  • 00008030-000A053901D0802E • ios         • iOS 13.3

• No issues found!

2 ответа

Я смог исправить проблему, у меня была эта строка в моем main.dart

await SystemChrome.setPreferredOrientations(
      [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown])

Это по какой-то причине остановило инициализацию флаттера.

Я изменил его на

 unawaited(SystemChrome.setPreferredOrientations(
      [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]))

и это сработало, как ожидалось.

Как только вы создадите кеш движка, его можно будет использовать в дальнейшем. // Кэширование предварительно нагретого FlutterEngine для использования FlutterFragment позже. FlutterEngineCache.getInstance() .put("my_engine_id", flutterEngine);

И используйте его во фрагменте флаттера как flutterFragment.withCachedEngine("my_engine_id"). Build();

Другие вопросы по тегам