簡述Flutter集成到Android原生項目

開發(fā)集成環(huán)境
[?] Flutter (Channel stable, v1.12.13+hotfix.9, on Mac OS X 10.14.6 18G103, locale zh-Hans-CN)

接觸使用Flutter也有段時間了摔竿,利用假期來梳理下在Flutter在使用層面的一些混編知識點诬留,其實整理起來會發(fā)現(xiàn)原生與Flutter的混編原生與RN的混編相似度很大蝗砾,其實所有的跨平臺框架談到和原生混編核心也就是方法調(diào)用和消息通信日熬,自然很相似了,這里簡單列以下幾點(前幾點方便你前期技術(shù)調(diào)研方案可行性研究盆繁,便于你快速去創(chuàng)建demo落實到項目中進行試手掀淘,后期再逐步梳理Dart語法筆記以及Flutter開發(fā)中的筆記)(這里就不講述Flutter的環(huán)境搭建了):
一、簡述Flutter集成到Android原生項目
二油昂、Android原生以AAR形式集成Flutter項目
三革娄、Flutter與原生(Android/IOS)的消息通信
四、Flutter中如何使用原生控件/組件
五冕碟、Flutter狀態(tài)管理Provider與Redux
六拦惋、Flutter升級及開發(fā)中遇到的問題匯總

image.png

在現(xiàn)有Android項目中集成Flutter項目,可參考官網(wǎng)方法Add Flutter to existing app安寺。
當然也可按照下列步驟操作即可厕妖。

1、 新建Flutter項目,選擇Flutter Module類型

  • 通過Android Studio 選擇 File -> New -> New Flutter Project -> Flutter Module 創(chuàng)建挑庶。
  • 通過命令行 $ flutter create -t module my_flutter 創(chuàng)建言秸。
    創(chuàng)建完成后,F(xiàn)lutter Module可正常運行到設(shè)備上迎捺。

2井仰、 在Android項目中集成Flutter項目

在宿主項目app下的的 build.gradle 里面,android {} 下修改:

android {
  //...
  compileOptions {
    sourceCompatibility 1.8
    targetCompatibility 1.8
  }
}

如何在原生項目中引入Flutter模塊

方式一:主module通過模塊依賴方式來依賴flutter

將flutter作為module破加,然后native主工程引入進來。這種方式適合參與人數(shù)比較少的項目雹嗦,如果有多人協(xié)作開發(fā)的大型項目就不合適了范舀,因為其他人首先要配置Flutter環(huán)境合是,而且團隊里面其他人還要配置module的依賴,都要熟悉flutter锭环,成本是很高的聪全。

  • 在工程的settings.gradle增加以下配置:
    // 加入下面配置
    setBinding(new Binding([gradle: this]))
    evaluate(new File(
            settingsDir.parentFile,
            'my_flutter/.android/include_flutter.groovy' //更改成自己的項目目錄
    ))
    
  • 在app 的gradle里添加依賴:
    implementation project(':my_flutter')
    
    弊端:
    這種方式適合參與人數(shù)比較少的項目,如果有多人協(xié)作開發(fā)的大型項目就不合適了辅辩,因為其他人首先要配置Flutter環(huán)境难礼,而且團隊里面其他人還要配置module的依賴,都要熟悉flutter玫锋,成本是很高的蛾茉。所以還需要以依賴jar/aar的方式來集成。
方式二:通過aar包引入
  • 將Flutter module打包成aar文件:
    進入根目錄下的.android目錄下執(zhí)行./gradlew assembleRelease 編譯成功后會在.android/Flutter/build/outputs/aar/flutter-release.aar 生成aar文件撩鹿。 (此種方式生成的aar包之前還能用谦炬,當前版本會報錯,稍后會提供通過使用fat-aar使用腳本打包方式)
    注意:暫時以第一種方式集成节沦,稍后在【二键思、Android原生以AAR形式集成Flutter項目】 會詳細講解方式二的使用。

3甫贯、在Android項目中加載Flutter頁面:

  • 繼承FlutterActivity加載Flutter頁面
    如果初期只是為了加載出對應的Flutter頁面吼鳞,簡單點可不繼承FlutterActivity創(chuàng)建自己的Activity,可直接使用FlutterActivity 叫搁。
    public class MyFlutterActivity extends FlutterActivity {
    
      // 定義Channel名稱
      private static final String CHANNEL_NATIVE = "com.cc.flutter/native";
    
     public static void openFlutter(Activity activity, String routerUrl){
          Intent intent = MyFlutterActivity.withNewEngine()
                .initialRoute(routerUrl)
                .build(activity);
          //設(shè)置Activity透明
          //intent.putExtra("background_mode","transparent");
          activity.startActivity(intent);
      }
    
      public static CCEngineIntentBuilder withNewEngine() {
          return new CCEngineIntentBuilder(MyFlutterActivity.class);
      }
    
      public static CCEngineIntentBuilder withNewEngine(Class<? extends FlutterActivity> activityClass) {
          return new CCEngineIntentBuilder(activityClass);
      }
    
      public static class CCEngineIntentBuilder extends NewEngineIntentBuilder {
    
        protected CCEngineIntentBuilder(Class<? extends FlutterActivity> activityClass) {
              super(activityClass);
          }
      }
    
      @Override
      public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
          GeneratedPluginRegistrant.registerWith(flutterEngine);
          //此處是Flutter與原生通信方法赔桌,暫時可不關(guān)注
          MethodChannel methodChannel = new MethodChannel(flutterEngine.getDartExecutor(), CHANNEL_NATIVE);
          methodChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
            @Override
            public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
                System.out.println("MethodChannel call.method:"+call.method+ "  call arguments:"+call.arguments.toString());
                switch (call.method){
                    case "envType":
                        result.success(2);
                        break;
                    default:
                        result.error("404", "未匹配到對應的方法"+call.method, null);
                }
            }
        });
    }
    
    此處的FlutterActivity使用的是import io.flutter.embedding.android.FlutterActivity; 而不是io.flutter.app.FlutterActivity , 貌似是說為了更好地支持將 Flutter 添加到現(xiàn)有項目的執(zhí)行環(huán)境,托管 Flutter 運行時的舊版 Android 平臺端包裝器位于 io.flutter.app.FlutterActivity 及其關(guān)聯(lián)的類現(xiàn)在已棄用常熙。新的包裝器 io.flutter.embedding.android.FlutterActivity 及相關(guān)類替代了他們纬乍。
    其實Flutter 1.2升級了很多東西,具體可參考 Upgrading pre 1.12 Android projects 一步步操作裸卫。(稍后我也會梳理在開發(fā)中需要操作的升級點及碰到的問題)
  • AndroidManifest注冊Activity:
    <!--flutter相關(guān) start-->
          <activity android:name=".activity.flutter.MyFlutterActivity"
              android:launchMode="singleTop"
              android:screenOrientation="portrait"
              android:windowSoftInputMode="adjustPan" />
    
          <activity
              android:name="io.flutter.embedding.android.FlutterActivity"
              android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
              android:hardwareAccelerated="true"
              android:theme="@style/AppTheme"
              android:windowSoftInputMode="adjustResize" >
          </activity>
          <meta-data
              android:name="flutterEmbedding"
              android:value="2" />
          <!--flutter相關(guān) end-->
    
  • Flutter中添加如下代碼:
    import 'dart:ui';
    import 'package:flutter/material.dart';
    
    void main() => runApp(_widgetForRoute(window.defaultRouteName));
    
    Widget _widgetForRoute(String route) {
      switch (route) {
        case 'route1':
          return MaterialApp(
            debugShowCheckedModeBanner: false,
            home: Scaffold(
              appBar: AppBar(
                title: Text('MyFlutter頁面'),
                centerTitle: true,
              ),
              body: Center(
                child: Column(
                  children: <Widget>[
                    Text('Flutter頁面仿贬,route=$route, params=$paramsJson'),
                    RaisedButton(
                      textColor: Colors.blue,
                      child: Text("跳轉(zhuǎn)原生頁面"),
                      onPressed:(){
                        // 跳轉(zhuǎn)原生頁面
                        Map<String, dynamic> result = {'name': '你好,${params["name"]}'};
                        nativeChannel.invokeMethod('jumpToNative', result);
                      },
                    ),
                  ],
                ),
              ),
            ),
          );
        default:
          return Center(
            child: Text('Unknown route: $route', textDirection: TextDirection.ltr),
          );
      }
    }
    

以上是Android原生項目中集成Flutter步驟墓贿。


這樣就實現(xiàn)了 Android 原生跳轉(zhuǎn)到 Flutter 頁面進行渲染, 可以邊開發(fā)茧泪,邊編譯看效果了。

注意:文中暫時以第一種方式集成聋袋,稍后在【二队伟、Android原生以AAR形式集成Flutter項目】 會詳細講解方式二的使用。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末幽勒,一起剝皮案震驚了整個濱河市嗜侮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖锈颗,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顷霹,死亡現(xiàn)場離奇詭異,居然都是意外死亡击吱,警方通過查閱死者的電腦和手機淋淀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來覆醇,“玉大人朵纷,你說我怎么就攤上這事∮琅В” “怎么了袍辞?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長憨奸。 經(jīng)常有香客問我革屠,道長,這世上最難降的妖魔是什么排宰? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任似芝,我火速辦了婚禮,結(jié)果婚禮上板甘,老公的妹妹穿的比我還像新娘党瓮。我一直安慰自己,他們只是感情好盐类,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布寞奸。 她就那樣靜靜地躺著,像睡著了一般在跳。 火紅的嫁衣襯著肌膚如雪枪萄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天猫妙,我揣著相機與錄音瓷翻,去河邊找鬼。 笑死割坠,一個胖子當著我的面吹牛齐帚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播彼哼,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼对妄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了敢朱?” 一聲冷哼從身側(cè)響起剪菱,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤摩瞎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后琅豆,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體愉豺,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年茫因,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杖剪。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡冻押,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盛嘿,到底是詐尸還是另有隱情洛巢,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布次兆,位于F島的核電站稿茉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏芥炭。R本人自食惡果不足惜漓库,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望园蝠。 院中可真熱鬧渺蒿,春花似錦、人聲如沸彪薛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽善延。三九已至少态,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間易遣,已是汗流浹背彼妻。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留训挡,地道東北人澳骤。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像澜薄,于是被迫代替她去往敵國和親为肮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容