android FlutterFragment 引入 Flutter ,dartEntrypoint配置多引擎,使用MethodChannel 双向数据交互通信

android FlutterFragment 引入 Flutter ,dartEntrypoint配置多引擎,使用MethodChannel 双向数据交互通信

android FlutterFragment 引入 Flutter ,dartEntrypoint配置多引擎,使用MethodChannel 双向数据交互通信_第1张图片

FlutterFragment 是 Flutter 提供的一个组件,用于在 Android 原生应用中嵌入 Flutter 模块作为 Fragment 使用。
FlutterFragment 允许开发者将 Flutter 视图集成到现有的 Android 应用架构中,作为 Fragment 使用。这种方式比使用 FlutterActivity 更加灵活,可以更好地与现有的 Android 导航和 UI 结构集成。

1. 基本创建方式
    // 使用默认配置创建 FlutterFragment
    FlutterFragment flutterFragment = FlutterFragment.createDefault();
    
2. 使用自定义配置创建
    // 使用构建器模式创建自定义配置的 FlutterFragment
    FlutterFragment flutterFragment = FlutterFragment.withNewEngine()
        .initialRoute("/my_route")
        .build();    

引擎配置   
    // 使用缓存的引擎
    FlutterFragment flutterFragment = FlutterFragment.withCachedEngine("my_engine_id")
        .build();

    // 使用新引擎
    FlutterFragment flutterFragment = FlutterFragment.withNewEngine()
        .dartEntrypoint("myCustomEntrypoint")
        .initialRoute("/my_route")
        .build();        
    
渲染模式和透明度
    // 设置渲染模式为纹理视图(默认)
    FlutterFragment flutterFragment = FlutterFragment.withNewEngine()
        .renderMode(RenderMode.texture)    // 设置渲染模式为纹理视图(默认)
        .renderMode(RenderMode.surface)    //设置渲染模式为表面视图
        .transparencyMode(TransparencyMode.transparent)    //设置透明背景
        .build();
        
添加到 Activity      
    // 在 Activity 中添加 FlutterFragment
    getSupportFragmentManager()
        .beginTransaction()
        .add(R.id.fragment_container, flutterFragment)
        .commit();    

方法调用        
    // 获取 FlutterEngine
    FlutterEngine flutterEngine = FlutterEngineCache.getInstance().get("my_engine_id");

    // 设置方法调用处理器
    flutterEngine.getDartExecutor().setMethodCallHandler((call, result) -> {
        if (call.method.equals("getBatteryLevel")) {
            int batteryLevel = getBatteryLevel();
            result.success(batteryLevel);
        } else {
            result.notImplemented();
        }
    });        
    
平台通道
    // 在 FlutterFragment 中设置平台通道
    new MethodChannel(flutterEngine.getDartExecutor(), "samples.flutter.dev/battery")
        .setMethodCallHandler((call, result) -> {
            // 处理来自 Flutter 的调用
        });    

        
实例:
缓存引擎一般在App种初始化
// 1. 预先缓存引擎 , flutterEngine也可以指定route和dartEntrypoint
FlutterEngine flutterEngine = new FlutterEngine(context);
flutterEngine.getDartExecutor().executeDartEntrypoint(
    DartExecutor.DartEntrypoint.createDefault()
);
FlutterEngineCache.getInstance().put("my_engine", flutterEngine);

// 2. 创建 Fragment
FlutterFragment flutterFragment = FlutterFragment.withCachedEngine("my_engine")
    .initialRoute("/settings")        //路由
    .dartEntrypoint("customMain")    //入口
    .renderMode(RenderMode.texture)
    .transparencyMode(TransparencyMode.transparent)
    .shouldAttachEngineToActivity(true)
    .build();

// 3. 添加 Fragment 到 Activity
getSupportFragmentManager()
    .beginTransaction()
    .add(R.id.fragment_container, flutterFragment)
    .commit();        
    
    
flutter文件:
    1、route配置:
    MaterialApp(
      initialRoute: '/settings', // 与 Java 中的 initialRoute 对应
      routes: {
        '/settings': (context) => SettingsScreen(),
        // 其他路由...
      },
    );
    
    2、如果你指定了 customMain,需要在 lib/main.dart 或其他 Dart 文件中定义这个函数:
    // 自定义入口函数
    @pragma('vm:entry-point') // 确保不会被 Tree Shaking 移除
    void customMain() {
      runApp(MyApp()); // 启动 Flutter 应用
    }
    
    
如果不使用lib/main.dart文件,比如lib/mytest.dart,具体调用如下:
    
// lib/mytest.dart
import 'package:flutter/material.dart';

// 自定义入口函数(必须添加 @pragma 注解)
@pragma('vm:entry-point')
void customMain() {
  runApp(MyCustomApp()); // 启动你的 Flutter 应用
}

class MyCustomApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: '/settings', // 与 Java 代码中的 initialRoute 对应
      routes: {
        '/settings': (context) => SettingsScreen(), // 你的设置页面
      },
    );
  }
}

class SettingsScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Settings')),
      body: Center(child: Text('This is the Settings Screen')),
    );
  }
}


Java调用:
// 在初始化使用自定义入口
FlutterEngine flutterEngine = new FlutterEngine(context);
flutterEngine.getDartExecutor().executeDartEntrypoint(
    new DartExecutor.DartEntrypoint(
        "lib/mytest.dart",  // 指定 Dart 文件路径
        "customMain"        // 指定入口函数

    )
);

// 缓存引擎
FlutterEngineCache.getInstance().put("my_engine", flutterEngine);

// 创建 Fragment
FlutterFragment flutterFragment = FlutterFragment.withCachedEngine("my_engine")
    .initialRoute("/settings")
    .dartEntrypoint("customMain")
    .build();  
    


FlutterFragment MethodChannel 双向(Android和Flutter)数据交互通信:
//Java代码
public class MainActivity extends AppCompatActivity {
    private static final String CHANNEL = "channel_name";

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

        FlutterFragment flutterFragment = FlutterFragment.withNewEngine()
                .initialRoute("/")
                .build();

        getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.fragment_container, flutterFragment)
                .commit();

        flutterFragment.getFlutterEngine().addEngineLifecycleListener(new FlutterEngine.EngineLifecycleListener() {
            @Override
            public void onPreEngineRestart() {}

            @Override
            public void onEngineWillDestroy() {}

            @Override
            public void onEngineCreated(@NonNull FlutterEngine flutterEngine) {
                new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
                        .setMethodCallHandler((call, result) -> {
                            if (call.method.equals("getBatteryLevel")) {
                                int batteryLevel = getBatteryLevel();
                                result.success(batteryLevel);
                            } else {
                                result.notImplemented();
                            }
                        });
                
                // 调用 Flutter 方法
                new Handler().postDelayed(() -> {
                    new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
                            .invokeMethod("showMessage", "Hello from Android", new MethodChannel.Result() {
                                @Override
                                public void success(Object o) {
                                    Log.d("MainActivity", "Flutter responded: " + o);
                                }
                                // 其他回调方法...
                            });
                }, 3000);
            }
        });
    }

    private int getBatteryLevel() {
        // 实现获取电池电量的逻辑
        return 50; // 示例值
    }
}

Flutter代码:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
  static const MethodChannel _channel = MethodChannel('channel_name');
  String _message = 'No message yet';
  int _batteryLevel = 0;

  @override
  void initState() {
    super.initState();
    _setupMethodChannel();
    _getBatteryLevel();
  }

  void _setupMethodChannel() {
    _channel.setMethodCallHandler((MethodCall call) async {
      switch (call.method) {
        case 'showMessage':
          setState(() {
            _message = call.arguments;
          });
          return 'Message received in Flutter';
        default:
          throw MissingPluginException('Not Implemented');
      }
    });
  }

  Future _getBatteryLevel() async {
    try {
      final int result = await _channel.invokeMethod('getBatteryLevel');
      setState(() {
        _batteryLevel = result;
      });
    } on PlatformException catch (e) {
      setState(() {
        _batteryLevel = -1;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('FlutterFragment Communication')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Battery Level: $_batteryLevel%'),
            SizedBox(height: 20),
            Text('Message from Native: $_message'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _getBatteryLevel,
              child: Text('Refresh Battery Level'),
            ),
          ],
        ),
      ),
    );
  }
}

你可能感兴趣的:(android FlutterFragment 引入 Flutter ,dartEntrypoint配置多引擎,使用MethodChannel 双向数据交互通信)