国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Flutter在Android上的熱更新方案

這篇具有很好參考價值的文章主要介紹了Flutter在Android上的熱更新方案。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1. 加載流程分析

flutter sdk版本:v3.0.3

dart版本:v2.17.5

1.1 FlutterApplication啟動流程

按照安卓原生啟動流程,當繼承FlutterApplication且在AndroidManifest.xml將application:name設(shè)置后,除Content Provider初始化,Application流程將首先執(zhí)行,此時FlutterApplication代碼如下:

Flutter在Android上的熱更新方案

FlutterApplication的onCreate只執(zhí)行了FlutterLoader類下的startInitialzation,并把自己作為Context傳入。

FlutterLoader對于startInitialzation有多個重載方法,此時將調(diào)用其中一個重載方法,并且生成了一個Settings傳入。

Flutter在Android上的熱更新方案

這時能看見startInitialization(@NonNull Context applicationContext, @NonNull Settings settings)才是實際執(zhí)行的方法,方法前半段限制了該方法只能運行在主線程,如運行在非主線程則直接拋出異常。

新建了一個initTask的Callable類型的回調(diào),并提交給了線程池執(zhí)行。此時可以看見flutterJni.loadLibrary(),這里就是在加載libflutter.so,flutterJni該成員變量是FlutterInjector.instance()生成單例時,通過工廠+建造者生成的一個實例。

initResultFuture將作為線程任務(wù)執(zhí)行的結(jié)果進行返回。

這說明了FlutterApplication執(zhí)行過程中,最重要的就是在子線程中System.loadLibrary("flutter"),并且在線程執(zhí)行完成后生成了initResultFuture,提供給后續(xù)操作。

Flutter在Android上的熱更新方案

Flutter在Android上的熱更新方案

1.2 FlutterActivity啟動流程

如果已繼承FlutterActivity作為LaunchActivity,且沒有設(shè)置自定義的Application,將不會執(zhí)行1.1的流程。

FlutterActivity時序圖如下所示:

(下圖出自得物技術(shù)專欄,鏈接:Flutter啟動流程分析之插件化升級探索_configureflutterengine_得物技術(shù)的博客-CSDN博客)

Flutter在Android上的熱更新方案

通過FlutterAcitivity的onCreate可以得知,大部分操作全部放在FlutterActivityAndFragmentDelegate中進行(代理模式)。

Flutter在Android上的熱更新方案

deletegate.onAttach將自己注入到方法。此時由于成員變量flutterEngine必定為空,則執(zhí)行setupFlutterEngine()。

Flutter在Android上的熱更新方案

Flutter在Android上的熱更新方案

進入setupFlutterEngine方法,此時可以通過getCachedEngineId,從FlutterEngineCache.getInstance()的map中,取出已經(jīng)生成的flutterEngine實例,getCachedEngineId()方法具體實現(xiàn)在FlutterActivity。這里說明在FlutterActivity啟動前預生成,可以有效減少onCreate()的時間。

當Cache和FlutterActivity子類中,都沒有提供FlutterEngine時,將自己生成一個FlutterEngine,其參數(shù)將通過FlutterActivity子類提供。此時可以發(fā)現(xiàn),通過FlutterActivity自動生成的Engine,automaticallyRegisterPlugins默認是為false的,這說明了此時需要手動注冊插件,在預生成的Engine中可以設(shè)置為true。

Flutter在Android上的熱更新方案

Flutter在Android上的熱更新方案

通過FlutterEngine的構(gòu)造方法,可以看見此時和FlutterApplication相似,生成了FlutterInjector的單例、flutterJni實例,并且初始化DartExecutor,生成了名為"flutter/isolate的channel,最后flutterJni與該executor的messager進行綁定。

此時由于flutterJni還未與Engine綁定,必定會執(zhí)行FlutterLoader的startInitialzation方法,具體邏輯1.1中已經(jīng)介紹。

之后將調(diào)用ensureInitialzationComplete的方法。

Flutter在Android上的熱更新方案

該方法執(zhí)行必定要在主線程中執(zhí)行,且Settings不能為空。

此時可以發(fā)現(xiàn),initResultFuture.get將掛起線程,并等待startInitialzation方法中執(zhí)行的子線程結(jié)果后,才會繼續(xù)向下執(zhí)行。

這時定義了一個shellArgs,用于存放執(zhí)行dart vm時攜帶的參數(shù),并且可以將外部的args傳入。

此時可以通過vm的參數(shù),發(fā)現(xiàn)JIT和AOT將加載不同的產(chǎn)物:

共同加載:libflutter.so

JIT:vm_snapshot_data、isolate_snapshot_data、kernel_blob.bin

AOT:libapp.so、libvmservice_snapshot.so(Profile)

在AOT的代碼段,注釋:

// Most devices can load the AOT shared library based on the library name
// with no directory path. Provide a fully qualified path to the library
// as a workaround for devices where that fails.

這里說明了當?shù)谝欢?/p>

"--" + AOT_SHARED_LIBRARY_NAME + "=" + flutterApplicationInfo.aotSharedLibraryName 路徑加載不到庫時,將自動加載第二段絕對路徑

"--"
+ AOT_SHARED_LIBRARY_NAME
+ "="
+ flutterApplicationInfo.nativeLibraryDir
+ File.separator
+ flutterApplicationInfo.aotSharedLibraryName

此時可以推斷,"--" + AOT_SHARED_LIBRARY_NAME + PATH,當加載成功庫,將不再執(zhí)行同參數(shù)的后續(xù)加載。

最后將用flutterJni.init將參數(shù)傳遞給nativeInit的jni映射方法中,在jni層啟動.

進入Jni層,可以通過flutter_main.cc文件下的Jni方法映射,找到實際引用的函數(shù)引用Init。

在Init方法中,將java層傳輸過來的args,增加了名叫flutter的參數(shù)

然后通過SettingsFromCommandLine生成了Settings類

Flutter在Android上的熱更新方案

Flutter在Android上的熱更新方案

Settings類中大部分都是作為設(shè)置的邏輯,在SettingsFromCommandLine方法中可以找到,aot_shared_library_name為數(shù)組,說明可以同時存在多個路徑。

并且全部存到Settings類的application_library_path中。

通過注解:

// Path to a library containing the application's compiled Dart code.
// This is a vector so that the embedder can provide fallback paths in
// case the primary path to the library can not be loaded.

可以得知,該屬性將作為默認加載路徑無法加載后的備選路徑。

Flutter在Android上的熱更新方案

通過dart vm的生命周期,dart_vm.cc文件中,Create方法會調(diào)用DartVMData的Create方法。

dart_vm_data.cc文件中的Create方法,將調(diào)用IsoSnapshotFromSettings函數(shù),該函數(shù)中會調(diào)用SearchMapping函數(shù)。

SearchMapping函數(shù)中表明了會根據(jù)Path查找NativeLibrary,并且查找native_library_symbol_name符號名,如果查找到,則不會繼續(xù)查找。此時可以證明只要Engine源碼中,不改變該符號名的名稱,則AOT產(chǎn)物替換加載方案為可行。

Flutter在Android上的熱更新方案

Flutter在Android上的熱更新方案

Flutter在Android上的熱更新方案

2. 熱更新Android方案

根據(jù)加載流程分析來看,如果不修改jni代碼,僅僅在java層進行改動,主要是在FlutterApplication與FlutterActivity上進行hook,將對于libapp.so的加載地址進行修改。

2.1 對于FlutterApplication的Hook

由1.1分析可以得出,F(xiàn)lutterApplication執(zhí)行過程中,已經(jīng)對于FlutterLoader進行了初始化,此時FlutterLoader的flutterInfoApplication屬性已經(jīng)填充了值,此時可以執(zhí)行之后,使用Reflect替換掉flutterInfoApplication里的內(nèi)容,將FlutterActivity加載庫的地址指向新的文件地址即可。

方案1:

描述:繼承FlutterApplication,修改flutterInfoApplication的aotSharedLibraryName屬性

侵入性:中

結(jié)果:無效

原因:

1.原flutterApplicationInfo的nativeLibraryDir指向的是/data/app,只讀不可寫權(quán)限且屬于私有文件目錄,無法移動下載的補丁文件到nativeLibraryDir的路徑下。

2.如將aotSharedLibraryName的絕對路徑,通過../強制轉(zhuǎn)成補丁文件目錄,會觸發(fā)jni路徑檢查錯誤。

錯誤信息如下:

library "/storage/emulated/0/Android/data/packagename/files/Download/-712256458372815974.so" ("/storage/emulated/0/Android/data/packagename/files/Download/-712256458372815974.so") needed or dlopened by "/data/app/~~F_tPgp6PDbt9Ug0opdFRsg==/packagename-W65G60j2V9GbWfwGQd_upw==/lib/arm64/libflutter.so" is not accessible for the namespace: [name="classloader-namespace", ld_library_paths="", default_library_paths="/data/app/~~F_tPgp6PDbt9Ug0opdFRsg==/packagename-W65G60j2V9GbWfwGQd_upw==/lib/arm64:/data/app/~~F_tPgp6PDbt9Ug0opdFRsg==/packagename-W65G60j2V9GbWfwGQd_upw==/base.apk!/lib/arm64-v8a", permitted_paths="/data:/mnt/expand:/data/data/packagename"]

從Log中可以看見libflutter.so文件對于加載的路徑,除了default_library_paths的,還有/data:/mnt/expand:/data/data/packagename?這2個路徑。

Flutter在Android上的熱更新方案

Flutter在Android上的熱更新方案

方案2:

描述:繼承FlutterApplication,修改flutterInfoApplication的aotSharedLibraryName、nativeLibraryDir屬性

侵入性:中

結(jié)果:無效

原因:原flutterApplicationInfo的nativeLibraryDir指向的是/data/app,只讀不可寫權(quán)限且屬于私有文件目錄,如將libflutter.so轉(zhuǎn)移到公共目錄,成本過高。且公共目錄會出現(xiàn)jni路徑檢查錯誤。具體原因可見方案1。

2.2 對于FlutterActivity的Hook

由1.2分析可以得出,即使onCreate執(zhí)行后,也不能完全保證flutterApplicationInfo的屬性被填充,必須等到子線程完成后才會注入數(shù)據(jù),所以不可以通過2.1的操作,對于flutterApplicationInfo通過反射注入自定義路徑。

通過1.2分析startInitialzationComplete方法,可以得出,F(xiàn)lutterActivity的args參數(shù),可以被傳入到方法中,與方法內(nèi)的參數(shù)進行合并,并傳入到j(luò)ni層。并且此時注入到args的路徑,必定順序在源代碼定義lib加載路徑之前,由此可以得出自定義路徑可以替代原路徑進行加載。

方案1:

描述:繼承FlutterActivity,重寫getFlutterShellArgs方法,使得vm args中加入一條指向新文件的路徑

侵入性:低

結(jié)果:有效

原因:通過1.2分析表明,jni層在根據(jù)路徑查找so文件時,如果查找到文件,且符號名正確,將不會繼續(xù)查找,所以修改getFlutterShellArgs傳入自定義的文件路徑,可以完成熱更新的操作。

注意:此時當下載到新文件時,必須將新文件從公共路徑(轉(zhuǎn)移/寫入)到/data/user/0/packageName路徑以下,由上面link的日志可以看出,/data/data路徑是可允許的加載路徑,而/data/data是/data/user/0的軟連接,且data/user/0/packageName路徑下是擁有可讀可寫權(quán)限的。

Flutter在Android上的熱更新方案

3.補丁下發(fā)方案設(shè)計

3.1補丁檢查

方案1:

在登錄賬號時觸發(fā)檢測,通過登錄時的接口來判定當時是否存在最新的補丁。

優(yōu)點:結(jié)構(gòu)簡單

缺點:如app不關(guān)閉且不重新登錄賬號,則無法觸發(fā)更新獲取,時效性差。服務(wù)器無法保證即時通知到app進行更新。

流程圖如下:

Flutter在Android上的熱更新方案

方案2:

在登錄賬號時建立長鏈接,通過服務(wù)器推送來判定是否存在補丁。

優(yōu)點:即時性高,服務(wù)器可以確保補丁下發(fā)過程中狀態(tài)是否正常。

缺點:結(jié)構(gòu)復雜,依賴于長鏈接的是否穩(wěn)定。

流程圖如下:

Flutter在Android上的熱更新方案

3.2 版本管理

用戶將上傳自身的包版本、補丁包版本和包名。

補丁下發(fā)將存在2種模式:

1.全量下發(fā)

上傳補丁后,將選擇要發(fā)布的版本號,然后將上傳補丁的分發(fā)至選擇的版本號,如該版本用戶本地補丁版本低于分發(fā)的補丁號,則將使用下發(fā)的補丁。

2.指定用戶下發(fā)

上傳補丁后,將針對指定用戶下發(fā)補丁。如該版本用戶本地補丁版本低于分發(fā)的補丁號,則將使用下發(fā)的補丁。文章來源地址http://www.zghlxwxcb.cn/news/detail-470395.html

到了這里,關(guān)于Flutter在Android上的熱更新方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • UnityC#腳本的熱更新原理

    想要了解Unity的熱更原理,必須要先了解Unity腳本的編譯和跨平臺機制。通常游戲的跨平臺主要指安卓和IOS端。Unity的官方腳本語言是C#,但也有不少項目會采用C# + Lua語言的方式進行開發(fā)。它們主要有三種跨平臺的形式:JIT、AOT、腳本語言。 Unity的C#代碼在代碼被打包時會被編

    2024年02月08日
    瀏覽(16)
  • Android 10.0 Settings 加載流程

    一、系統(tǒng)設(shè)置首頁 代碼路徑:packages/app/Settings/ 1 主界面加載: Settings的主界面是Settings.java,但是從Settings.java來看,除了大量的靜態(tài)類繼承SettingsActivity,就無其他有效信息了。但看其xml定義可以發(fā)現(xiàn)targetActivity屬性,實質(zhì)應是SettingsHomepageActivity.java。 先看其xml配置: SettingsH

    2024年02月05日
    瀏覽(28)
  • Flutter Android 打包保姆式全流程 2023 版

    Flutter Android 打包保姆式全流程 2023 版

    大家好,我是 17。 Flutter 打包的文章一共有兩篇 Flutter Android 打包保姆式全流程 2023 版 Flutter IOS 新建打包發(fā)布全流程 2023 版 本篇介紹 Android 的打包全流程。 為什么要寫這篇文章呢?對于一沒有 android 開發(fā)經(jīng)驗,從未有過打包經(jīng)歷的新人來說,要想成功打包,是很困難的。因

    2023年04月08日
    瀏覽(37)
  • Unity 熱更新方案和流程

    Unity 熱更新方案和流程

    在開發(fā)商業(yè)游戲時,熱更新是一個很重要的模塊,這里講的熱更新不是指僅僅修復Bug,而是進行游戲功能的更新。簡單來講,就是啟動游戲后,跑個條,下載資源和代碼,然后再進入游戲。本篇博客所寫的內(nèi)容并不是最優(yōu)的解,只是完成了熱更新這個事情而已,具體使用還需

    2024年02月09日
    瀏覽(20)
  • Android Studio更新新版本后無法創(chuàng)建flutter項目

    Android Studio更新新版本后無法創(chuàng)建flutter項目

    最新更新了AndroidStudio版本,發(fā)現(xiàn)無法創(chuàng)建flutter項目。 dart和flutter插件確認都已安裝,該有的環(huán)境配置都已配置。 最后與同事的插件作比較發(fā)現(xiàn)是Android APK Support這個插件沒勾選。 勾選后,點擊右下角的apply,重啟AndroidStudio。 然后去點擊File--New--New Flutter Project。

    2024年02月09日
    瀏覽(18)
  • Flutter網(wǎng)絡(luò)請求框架Dio源碼分析以及封裝(一)--請求流程分析

    利用flutter開發(fā)app也已經(jīng)有些時間了,這個過程中最多接觸到的就是網(wǎng)絡(luò)請求相關(guān)的代碼。自己目前項目中使用的是現(xiàn)在市面上最流行的網(wǎng)絡(luò)請求庫-dio,相對于flutter自帶的HttpClient來說,dio使用起來更簡單,功能更強大,支持全局配置、Restful API、FormData、攔截器、 請求取消、

    2024年02月09日
    瀏覽(24)
  • 【前端工程化面試題目】webpack 的熱更新原理

    【前端工程化面試題目】webpack 的熱更新原理

    可以在順便學習一下 vite 的熱更新原理,請參考這篇文章。 首先有幾個知識點需要明確 熱更新是針對開發(fā)過程中的開發(fā)服務(wù)器的,也就是 webpack-dev-server webpack 的熱更新不需要額外的插件,但是需要在配置文件中 devServer 屬性中配置 hot: true,需要安裝?webpack-dev-server 這個

    2024年02月19日
    瀏覽(95)
  • uniapp 制作 wgt 包(用于 app 的熱更新)

    uniapp 制作 wgt 包(用于 app 的熱更新)

    修改 manifest.json 的配置, 應用版本名稱 和 應用版本號 必須高于上一版的值。 打開 uni-admin 項目的升級中心 上傳后會自動生成下載鏈接 發(fā)布新版后,用戶打開app,后臺會自動下載 wgt 包完成熱更新 當用戶再次打開app,便會看到更新后的app效果

    2024年01月21日
    瀏覽(20)
  • UE5熱更新:Pak包的Cook、打包、加載全流程及踩坑經(jīng)驗分享

    UE5熱更新:Pak包的Cook、打包、加載全流程及踩坑經(jīng)驗分享

    探索UE5中Pak包加載的全流程,包括Cook、打包、加載等步驟,并分享在實踐中遇到的一些坑和解決方法。跟隨本教程,了解UE5與UE4的不同之處,以及如何成功實現(xiàn)熱更新功能。

    2024年02月03日
    瀏覽(41)
  • gin的熱啟動方案-air

    使用gin搭建服務(wù)的時候,在開發(fā)環(huán)境修改代碼,要關(guān)閉服務(wù),再重新打開代碼才能生效。 頻繁修改再打開是一個很低效的事情。所以需要一個工具,在修改完代碼之后可以熱啟動。 可以使用 air來完成。 air 不會自動配置路徑,需要我們添加 然后添加一個air的配置文件 執(zhí)行命

    2024年02月14日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包