Flutter入門進階之旅(十八)Flutter項目打包成aar集成到原生Android項目


前言
在前面的章節學習中我們已經掌握了從最基本的hello flutter到各種基本Widget、各種布局的使用再到多頁面切換路由的使用還有各種炫酷的提示跟dialog,還有關於網絡請求庫Dio的使用,至此我們完全可以使用flutter去開發一款獨立可運行的app了,但是基於現階段flutter技術棧還不是太成熟,純flutter項目上線風險還是比較大,所以跨平台的混合開發模式自然還是現階段嘗試flutter的主流方式,今天的分享我就跟大家一塊把我們寫好的flutter項目打包成aar文件嵌入到現有的Android項目中去。

課程目標
掌握flutter打包成aar的整體流程
利用fat-aar把flutter項目中的三方依賴打入aar資源包中
項目准備:
flutter端項目我采用的是本專欄的實例代碼項目:https://github.com/xiedong11/flutter_app,Android端原生項目為新建的一個hello world項目,flutter端的相關配置我會上傳到github倉庫中,原生Android項目比較簡單,我只在本博客中貼出部分關鍵代碼

1.flutter項目打包成aar
flutter端項目工程目錄
Flutter端項目工程目錄

上面截圖的flutter工程需要經過我們的改造才能作為一個aar的形式存在,要被打包成aar的flutter端的項目是作為一個獨立的module運行在宿主app(原生Android)中,所以我們需要修改兩個地方,讓我們打包出來的產物變成aar而不是獨立運行的apk。
1.1修改Android下的 build.gradle

// 1. 生成aar產物,需要把application改為library
apply plugin: 'com.android.library'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 28

lintOptions {
    disable 'InvalidPackage'
}

defaultConfig {
    // 2. flutter 作為寄存於其他app中的產物,所以不應該存在applicationId,所以注釋掉該行.
    //applicationId "com.zhuandian.flutterapp"
    minSdkVersion 16
    targetSdkVersion 28
    versionCode flutterVersionCode.toInteger()
    versionName flutterVersionName
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
    release {
        // TODO: Add your own signing config for the release build.
        // Signing with the debug keys for now, so `flutter run --release` works.
        signingConfig signingConfigs.debug
    }
}

}

  1. 2 修改Androidmanifest.xml文件

<uses-permission android:name="android.permission.INTERNET" />

<!--1.項目作為子項目寄存於原生app中,不需要icon、label等屬性,這里直接省去各種配置即可-->
<application>
    <!--android:name="io.flutter.app.FlutterApplication"-->
    <!--android:icon="@mipmap/ic_launcher"-->
    <!--android:label="flutter_app">-->
    <activity
        android:name=".MainActivity"
        android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
        android:hardwareAccelerated="true"
        android:launchMode="singleTop"
        android:theme="@style/LaunchTheme"
        android:windowSoftInputMode="adjustResize">


        <!--2.項目作為子項目寄存於原生app中,入口acitvity不需要配置LAUNCHER,不然應用集成到宿主app中,啟動會在桌面上生成兩個應用圖標-->
       
        <!--<meta-data-->
            <!--android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"-->
            <!--android:value="true" />-->

        <!--<intent-filter>-->
            <!--<action android:name="android.intent.action.MAIN" />-->

            <!--<category android:name="android.intent.category.LAUNCHER" />-->
        <!--</intent-filter>-->
    </activity>
    <activity android:name=".SecondActivity"></activity>
</application>
需要修改的地方,我都在源碼里留注釋了,這里就不展開贅述了,下面我們來通過gradle獲得編譯好的aar產物

因為在build.gradle 中,我們把apply plugin: 'com.android.application'修改成了,apply plugin: 'com.android.library'
所以,現在通過Terminal中我執行gradlew assembleRelease編譯出的產物會有原來的apk變成aar文件,文件輸出目錄為項目根目錄下的/bulid/app/outputs/aar
如下圖所示:
在這里插入圖片描述
1.3 Android端項目配置接入aar依賴
1.3.1 新建原生Android項目,我上述打包產出的aar文件作為依賴放入libs文件夾

在這里插入圖片描述
1.3.2 修改dependencies節點下的fileTree依賴配置,支持引入aar依賴支持

implementation fileTree(dir: 'libs', include: ['.jar','.aar'])
dependencies {
implementation fileTree(dir: 'libs', include: ['.jar','.aar'])
...
}
1.3.3 在原生Android項目中寫一個簡單的按鈕測試flutter項目

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    //初始化flutter運行環境
    FlutterMain.startInitialization(this)
    tv_test_aar.setOnClickListener {
        startActivity(Intent(this, com.zhuandian.flutterapp.MainActivity::class.java))
    }
}

}
至此,把flutter項目打包成aar導入到原生Android項目中的所有工程配置已經結束了,讀者可以測試上上述整個過程;但有時候我們的flutter項目並不是單純的flutter官方代碼,開發過程中少不了引入一些三方依賴,像上節課我們講到的Dio網絡請求庫,或者是通過pubspec.yaml引入的其他開源工具類,這種情況下,通過上邊的配置方式,你會發現第三方的依賴代碼是打不進aar包里的,下面我們就講解一下借助fat-aar的形式把三方依賴代碼打入aar包中去

2.flutter項目中存在三方依賴
通過上邊的配置,我們只能把純flutter項目打包成aar文件,換句話說,如果我們的flutter項目存在三方依賴是不能正常打包進flutter產物里的,這個時候我們就需要通過在Android原生項目中引入fat-aar配置,確保把flutter項目中的三方依賴正常打包進去flutter產物中去。

2.1修改項目工程目錄的build.gradle文件,引入fat-aar支持

buildscript {
repositories {
google()
jcenter()
}

dependencies {
    classpath 'com.android.tools.build:gradle:3.4.1'
    //引入fat-aar支持
    classpath 'com.kezong:fat-aar:1.1.7'
}

}
2.2 在上邊第一部分配置app文件下build.gradle基礎上,增加fat-aar相關配置,這里為了切換aar library運行環境,我引入isAarLibrary標志位作為切換環境開關,方便工程配置,具體代碼如下:

//是否作為依賴
boolean isAarLibrary = true

if (isAarLibrary) {
apply plugin: 'com.android.library'
} else {
apply plugin: 'com.android.application'
}

apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

if (isAarLibrary) {
//引入fat-aar
apply plugin: 'com.kezong.fat-aar'
}

android {
compileSdkVersion 28

lintOptions {
    disable 'InvalidPackage'
}

defaultConfig {
    // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
    if (!isAarLibrary) {
        applicationId "com.zhuandian.flutterapp"
    }

    minSdkVersion 16
    targetSdkVersion 28
    versionCode flutterVersionCode.toInteger()
    versionName flutterVersionName
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
    release {
        // TODO: Add your own signing config for the release build.
        // Signing with the debug keys for now, so `flutter run --release` works.
        signingConfig signingConfigs.debug
    }
}

}

flutter {
source '../..'
}

dependencies {
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test🏃1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
implementation 'androidx.appcompat:appcompat:1.0.0'

if (isAarLibrary) {
    //TODO 添加fat-aar處理flutter打包成aar中三方依賴
    def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
    def plugins = new Properties()
    def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
    if (pluginsFile.exists()) {
        pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
    }
    plugins.each { name, _ ->
        println name
        embed project(path: ":$name", configuration: 'default')
    }
}

}

2.3 AndroidManifest.xml清單文件中不需要增加額外配置,原生Android端喚起flutter項目aar包的方式也不需要修改,整個引入fat-aar的過程只是為了確保能把flutter項目中的三方依賴代碼打入到flutter產物中去,所以關於flutter打包成aar的操作跟第一步保持一致就行,第二步的配置,只是為了確保flutter項目中的三方依賴能正常打包進flutter產物中去

效果圖是我把本專欄的相關代碼作為一個aar集成到一個新建的原生Android項目中,效果圖如下:

在這里插入圖片描述
項目的完整代碼配置在https://github.com/xiedong11/flutter_app 中,讀者可以參考具體配置細節,筆者在寫本篇博文打包aar時的flutter 環境stable版本為 flutter v1.9.1,讀者盡量用官方穩定版的代碼做測試。

7人點贊
Flutter專欄

作者:謝棟_
鏈接:https://www.jianshu.com/p/7094c3ed03f1
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

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



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