Flutter android原生項目引入flutter module


前言:

各位同學的大家好,有段時間沒有給大家更新文章了,最近在學習flutter和安卓混合開發的知識點。所以就像總結一下,然后后分享給大家。 這一期文章的講的知識一定要有用到Android studio 所以用vscode開發同學要稍微改下IDE (但是這不是重點)
那么廢話不多說我們正式開始。

准備工作

需要安裝flutter的開發環境:大家可以去看看之前的教程:
1 win系統flutter開發環境安裝教程: https://www.jianshu.com/p/152447bc8718
2 mac系統flutter開發環境安裝教程:https://www.jianshu.com/p/bad2c35b41e3
效果圖:
image.png
image.png

具體實現

一 創建flutter_module 工程

  • 1用Android studio 創建或者命令都可以

image.png
image.png

  • 2 命令創建

flutter create -t module flutter_module

這里要注意安卓原生項目需要跟flutter_module在同一個目錄層級

第二步創建安卓原生工程

image.png

這個就比較簡單了 我就不多說了按照截圖一路下一步即可

三在Android 項目中進入flutter_module

  • 1 在原生Android項目里面的 app目錄下面的 build.gradle里面添加如下代碼
compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

image.png
我們知道這是使用Java 8所需要的配置,在這里的作用是為了解決版本兼容問題,如果不配置的話運行項目可能會報錯:Invoke-customs are only supported starting with Android O (--min-api 26)。

  • 2然后在項目根目錄下的setting.gradle文件中配置:

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

image.png

flutter_module 這個記得修改成自己的flutter module 的名稱 之后sync 一下·項目 即可導入成功

這里要注意我們在sync 的時候我們要同時打開flutter module 項目和原生安卓項目否則會失敗
image.png
sync之后我們發現原生工程工程的目錄結構里面多出一flutter名字的library module 的庫工程 我們需要在app目錄下的build.gradle 里面添加該module的依賴

  implementation project(':flutter')

image.png
這樣我們就講flutter_module工程引入到我們的Android項目項目里面來 當然flutter_module其實也是可以單獨運行的

android 原生頁面打開flutter頁面

  • 一添加普通的Flutter屏幕

Flutter提供FlutterActivity了在Android應用程序中顯示Flutter體驗的功能。像任何其他一樣Activity, FlutterActivity必須在您的帳戶中注冊 AndroidManifest.xml。將以下XML添加到 標簽AndroidManifestxml下的文件中application:

 <activity
android:name="io.flutter.embedding.android.FlutterActivity"
 android:theme="@style/Theme.Nativedemo"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
 android:hardwareAccelerated="true"
  android:windowSoftInputMode="adjustResize"
    />
  • 二 啟動activity

  • 1使用FlutterActivity.createDefaultIntent
 startActivity(FlutterActivity.createDefaultIntent(MainActivity.this));

這個示例假設您的Dart入口點稱為main(),初始Flutter路線為“ /”。無法使用更改Dart入口點Intent,但可以使用更改初始路線Intent。這個方法打開的是flutter默認入口不能自定義你想要打開的flutter的頁面

  • 2 使用 FlutterActivity.withNewEngine().initialRoute 這種方式
startActivity(FlutterActivity.withNewEngine().initialRoute("route_page").build(MainActivity.this));

這個就可以通過在 initialRoute 里面傳入你flutter module 項目里面配置的命名路由地址 從而選擇打開你想要打開的flutter頁面

  • 3 啟動flutteractivity並且傳值
    image.png
    image.png
    我們還是在通過 FlutterActivity.withNewEngine().initialRoute 在initialRoute 里面傳傳值
  startActivity(FlutterActivity.withNewEngine().initialRoute("{name:'xq9527'}").build(MainActivity.this));

flutter module 里面如何接收數據

import 'package:flutter/material.dart';
import 'dart:ui';
import 'my_home_page.dart';
import 'default_page.dart';

void main() => runApp(
     MyApp(initParams:window.defaultRouteName));
class MyApp extends StatelessWidget {
  String initParams = '';
  MyApp({this.initParams});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
        // routes: {
        //   "/": (context) => DefaultPage(title: '路由默認頁面'),
        //   'route_page':(context) => MyHomePage(title: '路由頁面Page1'),
        // },

     // home: "/",

      home: MyHomePage(title: this.initParams,),
    );
  }
}

在flutter module 我們需要在入口main方法中實例化的myapp 入口的時候 傳入window.defaultRouteName 我們的默認路由的參數 然后在我們的flutter中去使用原生傳過來的數據


使用FlutterEngine
package com.example.nativedemo;

import android.app.Application;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.engine.dart.DartExecutor;


/***
 *
 *創建人xuqing
 * 創建時間:2021/4/20
 * 類說明:啟動入口
 */

public class MyApplication extends Application {
    public static final String ENGINEID = "my_engine_id";
    @Override
    public void onCreate() {
        super.onCreate();
        initFlutterEngine();
    }
    private void initFlutterEngine(){
        // Instantiate a FlutterEngine.
        FlutterEngine flutterEngine = new FlutterEngine(this);
        flutterEngine.getNavigationChannel().setInitialRoute("route_page");// 配置默認啟動路由
        // 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(ENGINEID, flutterEngine);
    }
}

使用方式

   FlutterActivity.withCachedEngine(MyApplication.ENGINEI).build(MainActivity.this);

使用FlutterFragment

  • 默認啟動方式
 FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
        FlutterFragment flutterFragment=null;
        //默認啟動方式
        flutterFragment = FlutterFragment.createDefault();
        fragmentTransaction.add(R.id.main_framelayout, flutterFragment);
        fragmentTransaction.commit();
  • 指定路由頁面

FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
        FlutterFragment flutterFragment== FlutterFragment.withNewEngine()
                .initialRoute("route_page")
                .build();
        fragmentTransaction.add(R.id.main_framelayout, flutterFragment);
        fragmentTransaction.commit();
  • 使用FlutterEngine
  FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
        FlutterFragment flutterFragment== FlutterFragment.withCachedEngine(MyApplication.ENGINEID)
                .renderMode(RenderMode.surface)
                .build();
        fragmentTransaction.add(R.id.main_framelayout, flutterFragment);
        fragmentTransaction.commit();

還有可以使用flutterview 我這邊就不展開講了有興趣的同學可以查看官方文檔
Add Flutter to existing apps

最后總結

Android 原生引入flutter module 實現起來相對比較簡單 官方文檔也比較詳細,但是也有坑,我在文章中也提到了 這一期文章主要介紹了Android 引入flutter module 的基礎知識點 如果有紕漏請指正謝謝。最后希望我的文章能幫助到各位解決問題 ,以后我還會貢獻更多有用的代碼分享給大家。各位同學如果覺得文章還不錯 ,麻煩給關注和star,小弟在這里謝過啦


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM