Flutter plugin集成 aar 出現(xiàn)錯(cuò)誤

當(dāng)我們編寫flutter程序時(shí)候經(jīng)常會(huì)遇到要集成ios或者android sdk爱葵。其中android有些sdk不是jar而是aar。如果直接集成打包會(huì)是正常的甘苍,但是為了結(jié)構(gòu)清晰我們一般會(huì)把這些功能單獨(dú)用一個(gè)flutter plugin去集成灯荧。然后我們的flutter application再依賴這個(gè)plugin纹蝴。當(dāng)問我們?nèi)ゾ帉慺lutter plugin的時(shí)候會(huì)出現(xiàn)以下錯(cuò)誤海铆。

  1. 用android studio打開plugin項(xiàng)目的android文件夾會(huì)發(fā)現(xiàn)里面的java/kotlin文件的import都是灰色迹恐。里面的方法或者參數(shù)都是紅色。這是因?yàn)椴寮]有識(shí)別到flutter的sdk卧斟。(由于plugin最終是會(huì)被application去依賴殴边,所以項(xiàng)目編譯是可以通過的不會(huì)報(bào)錯(cuò))。這時(shí)我們只需在build.gradle文件的末尾添加以下內(nèi)容
//讀取配置
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') {
        reader-> localProperties.load(reader)
    }
}
//獲取flutter sdk路徑
def flutterRoot = localProperties.getProperty('flutter.sdk')
if(flutterRoot == null) {
    throw new GradleException('Flutter sdk not found.')
}
dependencies {
    compileOnly files("$flutterRoot/bin/cache/artifacts/engine/android-arm/flutter.jar")
    compileOnly("androidx.annotation:annotation:1.0.0")
}

上面這段腳本是用來依賴flutter.jar 以及annotation的珍语。用的是complieOnly所以不會(huì)參與編譯锤岸。這項(xiàng)文件就不再試紅色了。

  1. 編譯時(shí)候出現(xiàn)Error while evaluating property 'hasLocalAarDeps' of task ':xxxx插件名:bundleDebugAar'

Direct local .aar file dependencies are not supported when building an AAR. The resulting AAR would be broken because the classes and Android resources from any local .aar file dependencies would not be packaged in the resulting AAR.Previous versions of the Android Gradle Plugin produce broken AARs in this case too (despite not throwing this error). The following direct local .aar file dependencies of the :xxxx project caused this error: xxxxx\xxxx\xxxx.aar

這時(shí)候你看下你依賴aar的模式implementation fileTree(includes: [".aar"],dir:"libs")廊酣,implementation表示的是依賴只作用在本項(xiàng)目并參與編譯能耻。如果你是在flutter application中這么用是不會(huì)報(bào)錯(cuò)的赏枚。但是這是flutter pluigin亡驰。每個(gè)flutter plugin會(huì)編譯成一個(gè)aar晓猛。相當(dāng)于你把一個(gè)aar又編譯進(jìn)了另一個(gè)aar當(dāng)然會(huì)報(bào)錯(cuò)。所以你這里要換成compileOnly fileTree(includes: [".aar"],dir:"libs")凡辱。這樣就可以編譯通過了戒职。

  1. 當(dāng)編譯通過后你在使用到這個(gè)aar中的內(nèi)容時(shí)候又會(huì)報(bào)以下錯(cuò)誤

Caused by: java.lang.ClassNotFoundException: Didn't find class "XXXXXXX" on path: DexPathList[[zip file "/data/app/~~LmWMF6d-aNOCfQQ32bhOsQ==/

內(nèi)容可能和我的不一樣,但是意思是一樣的透乾。就是找不到這個(gè)aar中的類洪燥。這是為什么因?yàn)槟阌玫氖莄ompileOnly沒有吧aar編譯進(jìn)去。當(dāng)然會(huì)找不到乳乌。那么如何去解決捧韵?我網(wǎng)上找了很久很多答案都不行。最終自己折騰了出來汉操,方法有兩個(gè)

    1. 直接暴力 用rar解壓工具把a(bǔ)ar解壓了再来。把其中的jar包復(fù)制到android文件夾下的libs文件夾內(nèi)。把complieOnly改成implementation磷瘤。這個(gè)方法的思路是aar無法編譯進(jìn)aar如果是jar肯定是可以的芒篷。但是這個(gè)方法有個(gè)小問題。如果aar包中有些其他設(shè)置會(huì)丟失采缚。你需要手動(dòng)加入到你的項(xiàng)目中比如AndroidManifest.xml文件里的配置针炉,權(quán)限設(shè)定等。自己加入到自己插件項(xiàng)目的文件內(nèi)就行扳抽。
    1. 通過腳本把a(bǔ)ar復(fù)制到依賴此插件的主項(xiàng)目中篡帕,不參與插件的編譯。方法如下
      1贸呢、 把a(bǔ)ar復(fù)制到插件的android/libs文件夾中
      2赂苗、 在插件的android目錄的根部(和src同級(jí))新建aar_tools.gradle文件。
      3贮尉、 在文件內(nèi)寫入以下內(nèi)容
import java.util.zip.ZipEntry
import java.util.zip.ZipFile

// 拷貝aar的方法
static aarFileCopy(String srcPath,String desPath) {
    System.out.println("copy aar from <<${srcPath}>> to <<${desPath}>>")
    try {
        FileInputStream fis = new FileInputStream(srcPath)
        FileOutputStream fos = new FileOutputStream(desPath)
        byte[] data = new byte[1024*8]
        int len = 0
        while ((len = fis.read(data))!=-1) {
            fos.write(data,0,len)
        }
        fis.close()
        fos.close()
    }catch(Exception e) {
        e.printStackTrace()
    }
}
//把a(bǔ)ar拷貝進(jìn)入主項(xiàng)目的方法 com.example.android_control換成你自己的插件名
copyAar2Host('com.example.android_control')
void copyAar2Host(String pluginGroup) {
    Project currentProject = null
    Project appProject = null
    rootProject.allprojects.each {
        p->
            boolean  isApp = p.plugins.hasPlugin("com.android.application")
            println("<<${p.name}>> isHost ? ${isApp}")
            if (p.group == pluginGroup) {
                currentProject = p
                println("Plugin project name is $currentProject")
            }
            if(isApp) {
                appProject = p
                println("Host project name is <<${p.name}>>")
            }
    }
    Set<File> aarFiles = new HashSet<File>()
    if (appProject != null && currentProject != null) {
        File libs = new File("${currentProject.projectDir}","libs")
        if(libs.isDirectory()) {
            libs.listFiles().each {
                f->
                    if(f.name.endsWith(".aar")) {
                        println("The aar file name to be copied is <<${f.name}>>")
                        aarFiles.add(f)
                    }

            }
        }
        if (!aarFiles.isEmpty()) {
            File applibs = new File("${appProject.projectDir}${File.separator}libs")
            if(!applibs.isDirectory()) {
                applibs.mkdirs()
            }
            aarFiles.each {
                f->
                    File copyAar = new File("${appProject.projectDir}${File.separator}libs",f.name)
                    if(!copyAar.exists()) {
                        copyAar.createNewFile()
                        aarFileCopy(f.path,copyAar.path)
                    } else {

                    }
            }
            appProject.dependencies {
                implementation fileTree(dir:"${appProject.projectDir}${File.separator}libs",include:["*.jar","*.aar"])
            }
        }
    }
}

repositories{
    flatDir {
        dirs 'libs'
    }
}

  • 4拌滋、在插件的android build.gradle文件的以apply plugin: 'com.android.library'下一行位置插入apply from: './aar_tools.gradle',并確保這個(gè)文件中對(duì)aar的依賴是compileOnly
apply plugin: 'com.android.library'

apply from: './aar_tools.gradle'
...
//省略部分內(nèi)容
dependencies {
//    compileOptions files('libs/SdkApiJar-V1.0.0.221128.0.aar')
//    provided files('libs/SdkApiJar-V1.0.0.221128.0.aar.aar')
    compileOnly fileTree(includes: ["*.aar"],dir:"libs")
    compileOnly files("$flutterRoot/bin/cache/artifacts/engine/android-arm/flutter.jar")
    compileOnly("androidx.annotation:annotation:1.0.0")
}

修改完之后愉快的編譯吧猜谚。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末败砂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子魏铅,更是在濱河造成了極大的恐慌昌犹,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件览芳,死亡現(xiàn)場(chǎng)離奇詭異斜姥,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門铸敏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缚忧,“玉大人,你說我怎么就攤上這事杈笔∩了” “怎么了?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵蒙具,是天一觀的道長(zhǎng)球榆。 經(jīng)常有香客問我,道長(zhǎng)禁筏,這世上最難降的妖魔是什么持钉? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮篱昔,結(jié)果婚禮上右钾,老公的妹妹穿的比我還像新娘。我一直安慰自己旱爆,他們只是感情好舀射,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著怀伦,像睡著了一般脆烟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上房待,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天邢羔,我揣著相機(jī)與錄音,去河邊找鬼桑孩。 笑死拜鹤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的流椒。 我是一名探鬼主播敏簿,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼宣虾!你這毒婦竟也來了惯裕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤绣硝,失蹤者是張志新(化名)和其女友劉穎蜻势,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鹉胖,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡握玛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年够傍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挠铲。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡冕屯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出市殷,到底是詐尸還是另有隱情,我是刑警寧澤刹衫,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布醋寝,位于F島的核電站,受9級(jí)特大地震影響带迟,放射性物質(zhì)發(fā)生泄漏音羞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一仓犬、第九天 我趴在偏房一處隱蔽的房頂上張望嗅绰。 院中可真熱鬧,春花似錦搀继、人聲如沸窘面。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽财边。三九已至,卻和暖如春点骑,著一層夾襖步出監(jiān)牢的瞬間酣难,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工黑滴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留憨募,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓袁辈,卻偏偏與公主長(zhǎng)得像菜谣,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子晚缩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

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