美文网首页
Flutter 和 Android 混合开发(flutterBo

Flutter 和 Android 混合开发(flutterBo

作者: 许方镇 | 来源:发表于2020-03-28 12:55 被阅读0次

    flutter源码依赖简单demo(名字为onlyone):
    flutter混合开发中,会有flutter module和flutter plugin

    1.分别创建Flutter module和Flutter plugin

    2.Flutter module的pubspec.yaml中引入flutter plugin依赖

      only_one_flutter_plugin:
        path: /Users/xufangzhen/FlutterProjects/only_one_flutter_plugin
    

    3.将Flutter Module import进android工程

    android工程中修改点如下:
    1.settings.gradle文件中创建对flutter module进行评估,并引入

    setBinding(new Binding([gradle: this]))
    evaluate(new File(settingsDir, './only_one_flutter_module/.android/include_flutter.groovy'))

    include ':only_one_flutter_module'
    project(':only_one_flutter_module').projectDir = new File('xxx/only_one_flutter_module')

    4.在app module中的build.gradle中引入

    implementation project(path: ':flutter')
    implementation project(path: ':only_one_flutter_plugin')

    可能会遇到问题:

    1. 使用flutter v1.12,需要升级android的target sdk 为28及以上
    2. 如果你的工程没有使用androidx,那么你需要将flutter mo,dule中的pubspec.yaml文件里androidX: true去掉。
    3. setting include工程的工程 only_one_flutter_module后,原android工程无法断点调试,只需要将include的名字和路径改成only_one_flutter_module的父目录即可。

    引入闲鱼的 flutter_boost

    flutter_boost引入主要是解决native跳flutter重复创建flutter engine引题内存等问题,具体可以去闲鱼博客上了解。
    到了flutter sdk是1.12.x,flutter engine可以复用了,具体还没看

    具体使用如下:

    在flutter plugin中pubspec.yarml的,使用引入flutter_boost
    查看git上的介绍,不支持android x,flutter sdk是1.12的,使用以下配置

      flutter_boost:
        git:
          url: 'https://github.com/alibaba/flutter_boost.git'
          ref: 'task/task_v1.12.13_support_hotfixes'
    

    flutter plugin 的 android工程的app的build.gradle中添加

        api project(path: ':flutter_boost')
    

    在flutter module的main()方法中,调用plugin的初始化方法

    return MaterialApp(
          builder: OnlyOnePlugin.init({
            'one': (pageName, params, _) {
              return OnePage();
            },
            'twoPage': (pageName, params, _) {
              return TwoPage();
            },
          }),
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: MyHomePage(title: 'Flutter Demo Home Page'),
        );
    

    在flutter plugin的lib下创建的OnlyOnePlugin类,
    并增加注册、跳转和关闭方法

    class OnlyOnePlugin {
      static TransitionBuilder init(Map<String, PageBuilder> builders) {
        FlutterBoost.singleton.registerPageBuilders(builders);
        return FlutterBoost.init();
      }
    
      static Future<Map<dynamic, dynamic>> openPage(String pageName,
          {Map<dynamic, dynamic> data, Map<dynamic, dynamic> exts}) async {
        return FlutterBoost.singleton
            .open(changeToRouterUrl(pageName), urlParams: data, exts: exts);
      }
    
      static Future<bool> closePage(BuildContext context,
          {Map<String, dynamic> data, bool animate}) async {
        if (null == context) return Future.value(false);
        String uniqueId = BoostContainer.of(context)?.settings?.uniqueId ?? "";
        return FlutterBoost.singleton.close(uniqueId, result: data, exts: null);
      }
    
      static const MethodChannel _channel =
          const MethodChannel('only_one_flutter_plugin');
    
      static Future<String> get platformVersion async {
        final String version = await _channel.invokeMethod('getPlatformVersion');
        return version;
      }
    
     ……
    }
    

    在flutter plugin的android工程中,进行初始化、容器、bridge等工作开发

    初始化:

    在application的create方法中调用初始化方法

        public static void initBoost(Application application) {
            FlutterBoost.BoostLifecycleListener boostLifecycleListener = new FlutterBoost.BoostLifecycleListener() {
                @Override
                public void beforeCreateEngine() {
                }
    
                @Override
                public void onEngineCreated() {
                }
    
                @Override
                public void onPluginsRegistered() {
                }
    
                @Override
                public void onEngineDestroy() {
                }
            };
    
    
            INativeRouter router = new INativeRouter() {
                @Override
                public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
                    openPage(context, url, urlParams, requestCode, exts);
                }
            };
    
            Platform platform = new FlutterBoost
                    .ConfigBuilder(application, router)
                    .isDebug(isDebug)
                    .whenEngineStart(FlutterBoost.ConfigBuilder.ANY_ACTIVITY_CREATED)
                    .renderMode(FlutterView.RenderMode.texture)
                    .lifecycleListener(boostLifecycleListener)
                    .build();
            FlutterBoost.instance().init(platform);
        }
    
    遇到问题:
    1. FlutterBoostPlugin not register yet
      如果出现上面的问题,说明flutter module的android工程里,GeneratedPluginRegistrant
      无法自动生成。com.idlefish.flutterboost.FlutterBoostPlugin.registerWith(shimPluginRegistry.registrarFor("com.idlefish.flutterboost.FlutterBoostPlugin"));
      早期遇到这个问题需要手动注册,现在flutter_boost已经修复

    容器:

    可以自己写个Flutter容器,加载FlutterBoost里的flutterFragment
    再带个启动方法,(用路由的结合下路由,这里略去)

        public static void launch(Activity context, String pageName, JSONObject param, int requestCode) {
            Intent intent = new Intent(context, OnlyFlutterActivity.class);
            intent.putExtra(PAGE_NAME_KEY, pageName);
            intent.putExtra(ROUTER_PARAM_KEY, param);
            context.startActivityForResult(intent, requestCode);
        }
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.only_flutter_activity);
            String pageName = getIntent().getStringExtra(PAGE_NAME_KEY);
            HashMap params = (HashMap) getIntent().getSerializableExtra(ROUTER_PARAM_KEY);
    
            mFragment = new FlutterFragment.NewEngineFragmentBuilder().url(pageName).params(params).build();
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.fragment_stub, mFragment)
                    .commit();
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            mFragment.onActivityResult(requestCode, resultCode, data);
        }
    

    其中pageName就是在flutter module里注册进去的页面名。

    return MaterialApp(
          builder: OnlyOneFlutterPlugin.init({
            'onePage': (pageName, params, _) {
              print("params = " + params.toString());
              return OnePage(title: "标题1");
            },
            'twoPage': (pageName, params, _) {
              return TwoPage(title: "标题2");
            },
          }),
    ……
    

    上面看到已经看到了native跳flutter

    flutter跳flutter或者flutter跳native只需要调用flutter plugin lib下OnlyOneFlutterPlugin的openPage方法即可

    //flutter跳flutter
    OnlyOneFlutterPlugin.openPage("twoPage", data: params);
    
    //flutter跳native
    OnlyOneFlutterPlugin.openPage("MainActivity", data: params);
    

    flutter端不管跳flutter还是native都调用了
    FlutterBoost.singleton.open方法,最终会触发下面这个在初始化时的回调。

      INativeRouter router = new INativeRouter() {
                @Override
                public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
                    openPage(context, url, urlParams, requestCode, exts);
                }
            };
    

    我们只需要在openPage的方法中写下时跳native页面还是flutter页面即可。
    这里简单的示意下,正确的做法还是要在路由器的拦截器方法里写

        static void openPage(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
            if ("onePage".equals(url) || "twoPage".equals(url)) {
                ……
                OnlyFlutterActivity.launch ……
            } else {
                ……
                AppRouter.launch ……
            }
        }
    

    相关文章

      网友评论

          本文标题:Flutter 和 Android 混合开发(flutterBo

          本文链接:https://www.haomeiwen.com/subject/miyqdhtx.html