← Назад к вопросам

Как запускать FlutterActivity?

2.3 Middle🔥 181 комментариев
#Нативная интеграция

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как запускать FlutterActivity

FlutterActivity — это основной компонент Android для интеграции Flutter кода в Android приложение. Это Activity, которая загружает и отображает Flutter UI. Это особенно полезно при встраивании Flutter в существующее Android приложение, написанное на Kotlin/Java.

Основной способ — запуск через Intent

Самый простой способ запустить FlutterActivity:

// На стороне Dart/Flutter — если нужно передать данные
import 'package:flutter/services.dart';

class MainActivity extends FlutterActivity {
  // По умолчанию ничего не нужно делать
  // FlutterActivity автоматически загружает main.dart
}
// На стороне Kotlin (Android)
import io.flutter.embedding.android.FlutterActivity
import android.content.Intent
import android.os.Bundle

class MyAndroidActivity : AppCompatActivity() {
  
  fun launchFlutterActivity() {
    // Способ 1: простой запуск
    startActivity(
      Intent(this, FlutterActivity::class.java)
    )
    
    // Способ 2: запуск с route
    startActivity(
      FlutterActivity
        .withNewEngine()
        .initialRoute("/home")
        .build(this)
    )
  }
}

Запуск с передачей данных (Arguments)

Частый случай — передать данные из Android в Flutter:

// Android (Kotlin)
fun launchFlutterWithData() {
  val intent = FlutterActivity
    .withNewEngine()
    .initialRoute("/profile")
    .build(this)
  
  // Передаём данные через Bundle
  intent.putExtra("userId", "12345")
  intent.putExtra("userName", "John Doe")
  
  startActivity(intent)
}
// Flutter (Dart)
import 'dart:async';
import 'package:flutter/services.dart';

future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // Получить данные из Intent
  final args = await MethodChannel('com.example.app/data')
    .invokeMethod('getIntentData');
  
  runApp(MyApp(args: args));
}

Способ с использованием Engine

Для более сложных сценариев можно использовать явное управление FlutterEngine:

// Android (Kotlin)
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine

class MainActivity : FlutterActivity() {
  companion object {
    // Постоянный Engine, чтобы переиспользовать между Activities
    private var flutterEngine: FlutterEngine? = null
  }
  
  override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    
    // Сохраняем Engine
    MainActivity.flutterEngine = flutterEngine
    
    // Настраиваем каналы коммуникации
    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "com.example/channel")
      .setMethodCallHandler { call, result ->
        when (call.method) {
          "getData" -> {
            val data = mapOf("status" to "success", "value" to 42)
            result.success(data)
          }
          else -> result.notImplemented()
        }
      }
  }
}
// Flutter (Dart) — использование MethodChannel
import 'package:flutter/services.dart';

const platform = MethodChannel('com.example/channel');

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  String _data = 'Unknown';
  
  Future<void> _getData() async {
    try {
      final result = await platform.invokeMethod<Map>('getData');
      setState(() {
        _data = result?['value']?.toString() ?? 'Unknown';
      });
    } catch (e) {
      setState(() {
        _data = 'Error: $e';
      });
    }
  }
  
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text('Data from Android: $_data'),
          ElevatedButton(
            onPressed: _getData,
            child: Text('Get Data'),
          ),
        ],
      ),
    );
  }
}

Запуск FlutterActivity из Java

// Java (старый стиль)
import io.flutter.embedding.android.FlutterActivity;
import android.content.Intent;

public class MainActivity extends AppCompatActivity {
  
  public void launchFlutterScreen() {
    Intent intent = new Intent(this, FlutterActivity.class);
    // Можно добавить extra параметры
    intent.putExtra("route", "/details");
    startActivity(intent);
  }
}

Жизненный цикл и AndroidManifest

В AndroidManifest.xml нужно заявить FlutterActivity:

<!-- AndroidManifest.xml -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  
  <application>
    <!-- Основная Activity -->
    <activity
      android:name=".MainActivity"
      android:exported="true">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    
    <!-- FlutterActivity для встраивания Flutter -->
    <activity
      android:name="io.flutter.embedding.android.FlutterActivity"
      android:exported="true"
      android:theme="@style/LaunchTheme" />
      
  </application>
  
</manifest>

Лучшие практики

1. Переиспользование Engine

Для улучшения производительности лучше переиспользовать один Engine:

// Глобальный Engine (singleton)
object FlutterEngineManager {
  private var engine: FlutterEngine? = null
  
  fun getEngine(context: Context): FlutterEngine {
    if (engine == null) {
      engine = FlutterEngine(context)
      engine?.navigationChannel?.setInitialRoute("/")
    }
    return engine!!
  }
  
  fun destroy() {
    engine?.destroy()
    engine = null
  }
}

2. Обработка результатов

Если нужно получить результат из FlutterActivity:

// Запуск с ожиданием результата
startActivityForResult(
  Intent(this, FlutterActivity::class.java),
  REQUEST_CODE_FLUTTER
)

// Обработка результата
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
  super.onActivityResult(requestCode, resultCode, data)
  
  if (requestCode == REQUEST_CODE_FLUTTER && resultCode == RESULT_OK) {
    val result = data?.getStringExtra("result")
    // Обработать результат
  }
}
// Flutter — отправка результата
SystemChannels.platform.invokeMethod('SystemNavigator.pop', result);

3. Управление памятью

// Правильно очищать Engine при завершении
override fun onDestroy() {
  // FlutterActivity автоматически очищает Engine
  super.onDestroy()
}

Сравнение подходов

FlutterActivity с новым Engine:

  • Простой запуск
  • Каждый раз создаётся новый Engine (медленнее)
  • Хорошо для одноразовых переходов

FlutterActivity с кэшированным Engine:

  • Лучшая производительность
  • Требует управления lifecycle
  • Рекомендуется для частых переходов

Типичный сценарий: встраивание Flutter в существующее приложение

// MainActivity на Kotlin
class MainActivity : AppCompatActivity() {
  
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    
    // Android UI
    findViewById<Button>(R.id.button).setOnClickListener {
      // Запускаем Flutter когда нужно
      launchFlutter()
    }
  }
  
  private fun launchFlutter() {
    startActivity(
      FlutterActivity
        .withNewEngine()
        .initialRoute("/flutter_screen")
        .build(this)
    )
  }
}

Функция FlutterActivity решает проблему интеграции Flutter в существующие приложения, позволяя плавный переход между Android и Flutter частями приложения.