Flutter混编-与Android原生的混编

刚刚在Android项目 混编了flutter特意记录一下
具体的操作可以参考该链接flutter 与Android原生的混编
这次简要介绍下具体的流程,以及实际使用用遇到的问题

混编前的准备

  1. 新建flutter model
    注意不是flutter project,因为是要将flutter当做lib去引入Android项目里面,新建的flutter model 在项目的层级上要放到 与Android项目相同的层级 例如下图:
    Flutter混编-与Android原生的混编_第1张图片然后把flutter项目中lib下面的内容迁移到新建的flutter model中 记得添加相应的 引用在pubspec.yaml 文件中
  2. 在Android项目的 setting_gradle 里面添加 如下代码:
setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir.parentFile,
        'flutter_staff/.android/include_flutter.groovy'
))

其中需要注意的是:这段代码是针对你的项目名称是app的设置,如果你的项目名称不是app则需要下面的设置,需要制定你的 app项目名称,不然的话编译一直会出错

setBinding(new Binding([gradle: this, mainModuleName: 'airport']))
evaluate(new File(
        settingsDir.parentFile,
        'flutter_staff/.android/include_flutter.groovy'
))
  1. 然后sync下项目,此时项目中会出现很多东西,
    Flutter混编-与Android原生的混编_第2张图片其中flutter的lib就是咱们需要引入的,因为我用了阿里的 boost 所以会多生成一个boost的lib,其他的都是flutter运行需要的,没细究
  2. 在 app modul 中 build.gradle 中添加设置,添加依赖,至此前期准备就完成了
 implementation project(path: ':flutter')

正式调用

  1. 先说下通常的调用方式:
  • 调用flutter生成 view 并添加到当前activity
View flutterView = Flutter.createView(
        MainActivity.this,
        getLifecycle(),
        "route1"
);
FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(600, 800);
layout.leftMargin = 100;
layout.topMargin = 400;
addContentView(flutterView, layout);

  1. 通过添加fragment的方式去添加,需要在activity的xml文件里面添加一个FrameLayout
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fl_flutter_view, Flutter.createFragment("route1"));
fragmentTransaction.commit();
  1. 我用了 boost,他的调用方式与其他的不同,他封装了整个调用方式,与activity进行绑定,通过寻址的方式去调用,以及释放资源,还提供了页面传值,
  • 具体使用包括先创建 MyApplication 继承自flutterApplication ,然后在onCreate方法里面添加-
  FlutterBoostPlugin.init(object : IPlatform {
            override fun getApplication(): Application {
                return this@MyApplication
            }

            /**
             * get the main activity, this activity should always at the bottom of task stack.
             */
            override fun getMainActivity(): Activity {
                return BaseKTActivity.sRef?.get()!!
            }

            override fun isDebug(): Boolean {
                return false
            }

            /**
             * start a new activity from flutter page, you may need a activity router.
             */
            override fun startActivity(context: Context, url: String, requestCode: Int): Boolean {
                return PageRouter.openPageByUrl(context, url, requestCode)
            }

            override fun getSettings(): Map<*, *>? {
                return null
            }
        })

其中 pageRoute是一个页面路由

public class PageRouter {

    public static final String FLUTTER_PAGE_URL = "sample://flutterPage";

    public static boolean openPageByUrl(Context context, String url) {
        return openPageByUrl(context, url, 0);
    }

    public static boolean openPageByUrl(Context context, String url, int requestCode) {
        try {
            if (url.startsWith(FLUTTER_PAGE_URL)) {
                context.startActivity(new Intent(context, FlutterPageActivity.class));
                return true;
            }  else {
                return false;
            }
        } catch (Throwable t) {
            return false;
        }
    }
}

具体的FlutterpageActivity

class FlutterPageActivity : BoostFlutterActivity() {
    /**
     * 页面传参
     */
    override fun getContainerParams(): MutableMap {
        var params = mutableMapOf()
        params.put("opEmployeeID", LoginInfoUtils.getEmployeeID())
        params.put("deptID",LoginInfoUtils.getDeptID())
        params.put("token", LoginInfoUtils.getToken())
        params.put("registrationId", "")
        params.put("dataCommission", LoginInfoUtils.getDataCommission())
        return params
    }

    override fun onRegisterPlugins(registry: PluginRegistry?) {
        GeneratedPluginRegistrant.registerWith(registry)
    }

    /**
     * 路由-该名字配置在flutter中,会根据返回的名字打开相应的flutter页面
     */
    override fun getContainerName(): String {
        return "VipBindingState"
    }
}

至此,也就全部搞定了
总结下需要注意的问题:

  1. Android项目与flutter model要在同一层级
  2. 如果是多渠道打包,需要在flutter module的build.gradle中配置渠道信息
  3. 如果Android项目app module的名字不是”app“,需要配置project.rootProject.ext.mainModuleName。 问题解决
  4. 后续打包遇到的问题debug包正常,release包跳转flutter页面崩溃
    解决方法:配置flutter混淆https://www.jianshu.com/p/338422e3ecc1
    目前也就这些了

你可能感兴趣的:(flutter混编尝试)