Android原生集成flutter module步骤

重要!!!

明确自己使用的flutter 版本,不同的版本在原生页面承载flutter页面的时候方式不同,我使用的是1.17.1 。studio版本是3.5.2

阿里flutter_boost 插件可以方便的集成flutter module。但是flutter更新的版本很快,不同版本之间的有核心的api是废弃掉。flutter boost更新兼容达不到flutter sdk更新的速度。如果你要集成flutter boost要注意自己的flutter sdk版本和flutter_boost版本的保持统一。

创建项目流程

new -> new project ->//创建Android 原生项目
new -> new module -> flutter module //创建flutter module

此时项目编译 app目录下的build.gradle应该是这样的
在这里插入图片描述
在setting.gradle中应该是这样的
在这里插入图片描述
此时可以试着分别允许native项目和flutter项目。

下面是核心的类

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import io.flutter.embedding.android.FlutterView;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.embedding.engine.renderer.FlutterUiDisplayListener;

public class FlutterPlatformActivity extends AppCompatActivity {

    FlutterEngine mFlutter1Engine;
    FlutterView mFlutter1View;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_flutter2);
        //initFlutterEngine();
        mFlutter1Engine=FlutterEngineCache.getInstance().get("my_engine_id");
        mFlutter1View = createFlutterView();
        mFlutter1View.attachToFlutterEngine(mFlutter1Engine);
    }

    private FlutterView createFlutterView() {
        FlutterView flutterView = new FlutterView(this);
        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        FrameLayout flContainer = findViewById(R.id.fl_flutter);
        flContainer.addView(flutterView, lp);
        flContainer.setVisibility(View.INVISIBLE);
        FlutterUiDisplayListener listener = new FlutterUiDisplayListener() {
            @Override
            public void onFlutterUiDisplayed() {
                flContainer.setVisibility(View.VISIBLE);
            }

            @Override
            public void onFlutterUiNoLongerDisplayed() {

            }
        };
        flutterView.addOnFirstFrameRenderedListener(listener);
        return flutterView;
    }

    @Override
    protected void onResume() {
        super.onResume();
        mFlutter1Engine.getLifecycleChannel().appIsResumed();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mFlutter1Engine.getLifecycleChannel().appIsInactive();
    }

    @Override
    protected void onStop() {
        super.onStop();
        mFlutter1Engine.getLifecycleChannel().appIsPaused();
    }

    private void initFlutterEngine() {
        mFlutter1Engine = FlutterEngineCache.getInstance().get("flutter");
        if (mFlutter1Engine == null) {
            mFlutter1Engine = new FlutterEngine(this);
            mFlutter1Engine.getDartExecutor().executeDartEntrypoint(
                    DartExecutor.DartEntrypoint.createDefault()
            );
            FlutterEngineCache.getInstance().put("flutter", mFlutter1Engine);
        }
    }
}
//有两种方式 第一种在页面中初始化FlutterEngine 第二中在application中初始化  在FlutterEngineCache存储
package com.example.myapplication;

import android.app.Application;

import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.engine.dart.DartExecutor;

public class MyApplication extends Application {
    private FlutterEngine flutterEngine;

    @Override
    public void onCreate() {
        super.onCreate();
        // Instantiate a FlutterEngine.
        flutterEngine = new FlutterEngine(this);

        // Start executing Dart code to pre-warm the FlutterEngine.
        flutterEngine.getDartExecutor().executeDartEntrypoint(
                DartExecutor.DartEntrypoint.createDefault()
        );

        // Cache the FlutterEngine to be used by FlutterActivity.
        FlutterEngineCache
                .getInstance()
                .put("my_engine_id", flutterEngine);
    }
}

xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/fl_flutter"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

    </FrameLayout>
</FrameLayout>

官方描述

/**
 * A single Flutter execution environment.
 *
 * <p>The {@code FlutterEngine} is the container through which Dart code can be run in an Android
 * application.
 *
 * <p>Dart code in a {@code FlutterEngine} can execute in the background, or it can be render to the
 * screen by using the accompanying {@link FlutterRenderer} and Dart code using the Flutter
 * framework on the Dart side. Rendering can be started and stopped, thus allowing a {@code
 * FlutterEngine} to move from UI interaction to data-only processing and then back to UI
 * interaction.
 *
 * <p>Multiple {@code FlutterEngine}s may exist, execute Dart code, and render UIs within a single
 * Android app. Flutter at this point makes no guarantees on the performance of running multiple
 * engines. Use at your own risk. See https://github.com/flutter/flutter/issues/37644 for details.
 *
 * <p>To start running Dart and/or Flutter within this {@code FlutterEngine}, get a reference to
 * this engine's {@link DartExecutor} and then use {@link
 * DartExecutor#executeDartEntrypoint(DartExecutor.DartEntrypoint)}. The {@link
 * DartExecutor#executeDartEntrypoint(DartExecutor.DartEntrypoint)} method must not be invoked twice
 * on the same {@code FlutterEngine}.
 *
 * <p>To start rendering Flutter content to the screen, use {@link #getRenderer()} to obtain a
 * {@link FlutterRenderer} and then attach a {@link RenderSurface}. Consider using a {@link
 * io.flutter.embedding.android.FlutterView} as a {@link RenderSurface}.
 *
 * <p>Instatiating the first {@code FlutterEngine} per process will also load the Flutter engine's
 * native library and start the Dart VM. Subsequent {@code FlutterEngine}s will run on the same VM
 * instance but will have their own Dart <a
 * href="https://api.dartlang.org/stable/dart-isolate/Isolate-class.html">Isolate</a> when the
 * {@link DartExecutor} is run. Each Isolate is a self-contained Dart environment and cannot
 * communicate with each other except via Isolate ports.
 */
1.一个Flutter执行环境 是dart运行在Android上面最小的容器
2.在FlutterEngine中的dart代码 既可以运行在后台,也可以进行(FlutterRenderer)ui交互
3.初始化FlutterEngine时,加载FlutterEngine的native libs并且启动DartVM
4.DartVM中有多个FlutterEngine。
5.FlutterEngine运行在各自的Isolate中(类似于Android中的线程
),他们的内存数据不共享,需要通过Isolate事先设置的port(顶级函数)通讯。

构造方法

只说核心
在这里插入图片描述可以看到在flutterEngine中有几个方法

//Finds Flutter resources in an application APK and also loads Flutter's native library
  • FlutterLoader :FlutterLoader 在应用程序APK中查找Flutter资源,并加载Flutter的本机库。
Interface between Flutter embedding's Java code and Flutter engine's C/C++ code.
  • FlutterJNI :Flutter嵌入的Java代码和Flutter引擎的C / C ++代码之间的接口。
    FlutterRenderer:呈现FlutterEngine
    DartExecutor:配置,引导并开始执行Dart代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值