android 原生混編 flutter 並使用 flutter_boost進行跳轉的步驟以及注意事項

the0king發表於2020-10-31

匯入步驟: 

1.將flutter_module放在專案中,與app module平級。

2.在專案build.gradle裡面,加入以下程式碼:

include ':app'
// 加入下面配置
setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir.parentFile,
        'inininhelper/flutter_module/.android/include_flutter.groovy'
))

3.在Build →  Rebuild Project 之後,在app的build.gradle裡面新增

dependencies {
    ...
    implementation project(':flutter')
    implementation project(':flutter_boost')
}

4.在Build →  Rebuild Project 之後,將以下activity新增到AndroidManifest.xml:

<!-- 宣告載入flutter介面的activity-->
<activity
    android:name="com.idlefish.flutterboost.containers.BoostFlutterActivity"
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
    android:hardwareAccelerated="true"
    android:theme="@style/Theme.AppCompat"
    android:windowSoftInputMode="adjustResize">
    <!--新增loading-->
    <!--如果不新增meta-data會出現黑色閃屏-->
    <!--如果只新增name,不新增resource會執行不起來-->
    <!--resource需設定一個loading圖片-->
    <meta-data
        android:name="io.flutter.embedding.android.SplashScreenDrawable"
        android:resource="@drawable/ic_launcher_background" />
</activity>

5.在Application中初始化flutter_boost:

package com.example.mixdemo;

import android.app.Application;
import android.content.Context;
import android.util.Log;

import com.idlefish.flutterboost.FlutterBoost;
import com.idlefish.flutterboost.Platform;
import com.idlefish.flutterboost.Utils;
import com.idlefish.flutterboost.interfaces.INativeRouter;

import java.util.Map;

import io.flutter.embedding.android.FlutterView;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.view.FlutterMain;

public class BaseApplication extends Application {

    private String TAG = "test";

    @Override
    public void onCreate() {
        super.onCreate();
        // 初始化
        initFlutterBoost();
    }

    private void initFlutterBoost() {
        //路由,Flutter 啟動Native頁面的時候回撥這裡
        INativeRouter router = new INativeRouter() {
            @Override
            public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
                Log.i(TAG, "路由--INativeRouter:url=" + url);
                Log.i(TAG, "路由--INativeRouter:requestCode=" + requestCode);
                Log.i(TAG, "路由--INativeRouter:urlParams=" + urlParams);
                Log.i(TAG, "路由--INativeRouter:exts=" + exts);

                String assembleUrl = Utils.assembleUrl(url, urlParams);
                PageRouter.openPageByUrl(context, assembleUrl, urlParams);
            }
        };
        //外掛註冊
        FlutterBoost.BoostPluginsRegister pluginsRegister = new FlutterBoost.BoostPluginsRegister() {
            @Override
            public void registerPlugins(PluginRegistry mRegistry) {
                GeneratedPluginRegistrant.registerWith(mRegistry);

            }
        };
        //配置
        Platform platform = new FlutterBoost.ConfigBuilder(this, router)
                .isDebug(true)
                .whenEngineStart(FlutterBoost.ConfigBuilder.ANY_ACTIVITY_CREATED)
                .renderMode(FlutterView.RenderMode.texture)
                .pluginsRegister(pluginsRegister)
                .build();

        //初始化flutter_boost
        FlutterBoost.instance().init(platform);

    }
}

6.android 呼叫flutter頁面:

val params: MutableMap<String, String> = HashMap()
params["test1"] = "v_test1"
params["test2"] = "v_test2"
findViewById<Button>(R.id.button)
    .setOnClickListener {
        PageRouter.openPageByUrl(this, PageRouter.FLUTTER_PAGE_URL, params);
        Toast.makeText(this, "已傳送", Toast.LENGTH_SHORT).show()
    }

7.PageRouter頁面

package com.example.mixdemo;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import com.idlefish.flutterboost.containers.BoostFlutterActivity;

import java.util.HashMap;
import java.util.Map;

public class PageRouter {

    public final static Map<String, String> pageName = new HashMap<String, String>() {{

        put("first", "first");
        put("second", "second");
        put("tab", "tab");
        put("sample://abnormalOrderPage", "abnormalOrderPage");
    }};

    public static final String NATIVE_PAGE_URL = "sample://nativePage";
    public static final String FLUTTER_PAGE_URL = "sample://abnormalOrderPage";
    public static final String FLUTTER_FRAGMENT_PAGE_URL = "sample://flutterFragmentPage";

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

    public static boolean openPageByUrl(Context context, String url, Map params, int requestCode) {

        String path = url.split("\\?")[0];

        Log.i("openPageByUrl", path);

        try {
            if (pageName.containsKey(path)) {
                //開啟指定url的flutter頁面
                Intent intent = BoostFlutterActivity.withNewEngine().url(pageName.get(path)).params(params)
                        .backgroundMode(BoostFlutterActivity.BackgroundMode.opaque).build(context);
                if (context instanceof Activity) {
                    Activity activity = (Activity) context;
                    activity.startActivityForResult(intent, requestCode);
                } else {
                    context.startActivity(intent);
                }
                return true;
            } else if (url.startsWith(FLUTTER_FRAGMENT_PAGE_URL)) {
                //開啟flutter建立的fragment
//                context.startActivity(new Intent(context, FlutterFragmentPageActivity.class));
                return true;
            } else if (url.startsWith(NATIVE_PAGE_URL)) {
                //開啟原生Activity
//                context.startActivity(new Intent(context, NativePageActivity.class));
                return true;
            }
            return false;
        } catch (Throwable t) {
            return false;
        }
    }
}

注意事項(重要)

1.注意flutter_boost的版本和與之對應的flutter sdk

Flutter Boost Release VersionSupport Flutter SDK VersionDescriptionSupport AndroidX?
1.9.1+21.9.1-hotfixesRename the version number and start supporting androidx by defaultYes
1.12.13+31.12.13-hotfixes支援androidxYes
1.17.11.17.1支援androidxYes

 

Flutter Boost BranchSupport Flutter SDK VersionDescriptionSupport AndroidX?
v1.9.1-hotfixes1.9.1-hotfixesfor androidxYes
v1.12.13-hotfixes1.12.13-hotfixesfor androidxYes
v1.17.1-hotfixes1.17.1for androidxYes

如果不注意這個會出現異常,版本不一致導致庫方法不一致。

2.注意flutter module 的pubspec.yaml檔案版本資訊

如果出現了

The current Dart SDK version is 2.5.0.

Because yybb_flutter depends on flutter_screenutil >=1.1.0 which requires SDK version >=2.6.0 <3.0.0, version solving failed.
pub get failed (1)

類似報錯資訊,那麼需要將pubspec.yaml裡的flutter_screenutil:^2.3.0改成flutter_screenutil:any,重新編譯後檢視pubspec.lock的版本資訊,並且修改成該版本:

類似這樣:

flutter_screenutil:
  dependency: "direct main"
  description:
    name: flutter_screenutil
    url: "https://pub.flutter-io.cn"
  source: hosted
  version: "1.0.2"

修改為1.0.2,如此類推。

相關文章