【r_upgrade】快來(lái)升級(jí)你的Flutter應(yīng)用

image

介紹

在移動(dòng)開(kāi)發(fā)過(guò)程中,應(yīng)用升級(jí)是必不可少的一個(gè)環(huán)節(jié),所以,r_upgrade應(yīng)用升級(jí)插件就出現(xiàn)了,這里先鼓掌歡迎????,下面是使用介紹

r_upgrade

Android和IOS的升級(jí)應(yīng)用插件==Flutter應(yīng)用升級(jí)插件

  • 網(wǎng)頁(yè)鏈接形式升級(jí)
  • apk下載形式升級(jí)使用Service或者DownloadManager
  • 跳轉(zhuǎn)到應(yīng)用商店升級(jí)
  • Android熱更新
  • Android增量升級(jí)

開(kāi)始吧

1.使用插件:

pubspec.yaml文件添加下面代碼

dependencies:
  r_upgrade: last version

2.使用打開(kāi)鏈接的方式進(jìn)行更新(AndroidIOS通用)

    void upgradeFromUrl()async{
        bool isSuccess =await RUpgrade.upgradeFromUrl(
                    'https://www.baidu.com',
                  );
        print(isSuccess);
    }

Android平臺(tái)

1.跳轉(zhuǎn)到應(yīng)用商店升級(jí)

    void upgradeFromAndroidStore(){
       bool isSuccess = await RUpgrade.upgradeFromAndroidStore(AndroidStore.BAIDU);
       print('${isSuccess?'跳轉(zhuǎn)成功':'跳轉(zhuǎn)失敗'}');
    }

2.通過(guò)下載鏈接進(jìn)行apk下載

注意,在Android應(yīng)用中,請(qǐng)確保AndroidManifest.xml中聲明以下權(quán)限,并在6.0系統(tǒng)上進(jìn)行動(dòng)態(tài)授權(quán),不然會(huì)調(diào)用升級(jí)方法將拋出權(quán)限異常

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

1.添加升級(jí)下載進(jìn)度監(jiān)聽(tīng)

RUpgrade.stream.listen((DownloadInfo info){
  ///...
});

info 里包含的信息如下:

字段 含義
(int) id 當(dāng)前下載任務(wù)的id
(int) max_length 所需下載的總大小 (bytes)
(int) current_length 當(dāng)前已下載的大小 (bytes)
(double) percent 當(dāng)前下載進(jìn)度(0-100)
(double) planTime 計(jì)劃下載完成所需時(shí)間/秒 (需要.toStringAsFixed(0))
(String) path 當(dāng)前下載的文件路徑
(double) speed 當(dāng)前下載的速度kb/s
(DownloadStatus) status 當(dāng)前下載狀態(tài)
STATUS_PAUSED 下載已暫停
STATUS_PENDING等待下載
STATUS_RUNNING下載中
STATUS_SUCCESSFUL下載成功
STATUS_FAILED下載失敗
STATUS_CANCEL下載取消

注意: 部分http下載鏈接可能返回 max_length = -1,請(qǐng)自行判斷

2.立即升級(jí)你的應(yīng)用

目前分為兩部分
useDownloadManager:

  • true: 調(diào)用系統(tǒng)的DownloadManager進(jìn)行下載
    • 優(yōu)勢(shì):接入簡(jiǎn)單,無(wú)需擔(dān)心操作,下載全由系統(tǒng)管理
    • 劣勢(shì):無(wú)法使用http方式進(jìn)行下載,無(wú)法在下載過(guò)程中點(diǎn)擊通知欄進(jìn)行暫停,無(wú)法根據(jù)有無(wú)網(wǎng)絡(luò)進(jìn)行暫停和繼續(xù)下載,適配機(jī)型問(wèn)題等
    • 支持的方法:RUpgrade.streaminstallcancel
  • false: 調(diào)用Service進(jìn)行下載(默認(rèn)使用)
    • 優(yōu)勢(shì):功能較全,支持http/https下載,支持網(wǎng)絡(luò)斷開(kāi)后自動(dòng)暫停下載,連接上后繼續(xù)下載,支持?jǐn)帱c(diǎn)續(xù)傳,支持查詢(xún)最后一次下載等
    • 劣勢(shì):暫無(wú)發(fā)現(xiàn),如果發(fā)現(xiàn)bug歡迎提issue.
    • 支持的方法:默認(rèn)全部
    // [isAutoRequestInstall] 下載完成后自動(dòng)彈出安裝
    // [apkName] 安裝包的名字(需要包含.apk)
    // [notificationVisibility] 通知欄顯示方式
    // [useDownloadManager] 是否使用DownloadManager,默認(rèn)不使用(DownloadManager不支持http下載,下載手動(dòng)暫停,斷點(diǎn)續(xù)傳等,不建議使用)
    // [upgradeFlavor] 升級(jí)的口味,默認(rèn)全量升級(jí)(默認(rèn))
    void upgrade() async {
      int id = await RUpgrade.upgrade(
                 'https://raw.githubusercontent.com/rhymelph/r_upgrade/master/apk/app-release.apk',
                 apkName: 'app-release.apk',isAutoRequestInstall: true);
    }

新增升級(jí)的口味:(不支持使用DownloadManager下載)

enum RUpgradeFlavor {
  normal, // 全量升級(jí)
  hotUpgrade, // 熱更新
  incrementUpgrade, // 增量升級(jí)
}

3. 取消下載

    void cancel() async {
      bool isSuccess=await RUpgrade.cancel(id);
    }

4. 安裝應(yīng)用

    void install() async {
      bool isSuccess=await RUpgrade.install(id);
    }

5. 暫停下載

    void pause() async {
      bool isSuccess=await RUpgrade.pause(id);
    }

6. 繼續(xù)下載

    void pause() async {
      bool isSuccess=await RUpgrade.upgradeWithId(id);
      // 返回 false 即表示從來(lái)不存在此ID
      // 返回 true
      //    調(diào)用此方法前狀態(tài)為 [STATUS_PAUSED]、[STATUS_FAILED]、[STATUS_CANCEL],將繼續(xù)下載
      //    調(diào)用此方法前狀態(tài)為 [STATUS_RUNNING]、[STATUS_PENDING],不會(huì)發(fā)生任何變化
      //    調(diào)用此方法前狀態(tài)為 [STATUS_SUCCESSFUL],將會(huì)安裝應(yīng)用
      // 當(dāng)文件被刪除時(shí),重新下載
    }

7. 獲取最后一次下載的ID

該方法只會(huì)尋找當(dāng)前應(yīng)用版本名和版本號(hào)下下載過(guò)的ID

    void getLastUpgradeId() async {
     int id = await RUpgrade.getLastUpgradedId();
    }

8. 獲取ID對(duì)應(yīng)的下載狀態(tài)

    void getDownloadStatus()async{
    DownloadStatus status = await RUpgrade.getDownloadStatus(id);
   }

9. 增量升級(jí)

  • 1.下載bsdiff工具到本地
  • 2.準(zhǔn)備兩個(gè)安裝包,一個(gè)是即將需要升級(jí)的安裝包(old.apk)、一個(gè)是你需要更新的安裝包(new.apk)
  • 3.在命令行切換到上面下載的bsdiff目錄下,運(yùn)行命令./bsdiff old.apk new.apk increment.patch
  • 4.將上面生成的increment.patch上傳到服務(wù)器
  • 5.調(diào)用RUpgrade.upgrade(...,upgradeFlavor:RUpgradeFlavor.incrementUpgrade)方法進(jìn)行下載,即可
  • 6.調(diào)用RUpgrade.install(id)進(jìn)行安裝

代碼如下:

    int id;
    void incrementUpgrade(){
        id = await RUpgrade.upgrade(
                'https://mydata-1252536312.cos.ap-guangzhou.myqcloud.com/r_upgrade.patch',
                fileName: 'r_upgrade.patch',
                useDownloadManager: false,
                isAutoRequestInstall: false,
                upgradeFlavor: RUpgradeFlavor.incrementUpgrade,
              );
    }

    void install(){
        try {
            await RUpgrade.install(id);
        } catch (e) {
            _state.currentState
                .showSnackBar(SnackBar(content: Text('增量更新失敗!')));
        }
    }

10. 熱更新

  • 你可以使用升級(jí)返回的id進(jìn)行熱更新,下載的文件需要將新版本生成的isolate_snapshot_datakernel_blob.binvm_snapshot_data打進(jìn)zip文件中下載
    步驟:
    • 運(yùn)行 flutter clean 清理build文件
    • 運(yùn)行 flutter build bundle 生成需要的產(chǎn)物,下面標(biāo)記星號(hào)為必須文件
|- AssetManifest.json
|- FontManifest.json
|- fonts
    |- ...
|- isolate_snapshot_data *
|- kernel-blob.bin       *
|- LICENSE
|- packages
    |- ...
|- vm_snapshot_data      *
- 將標(biāo)記星號(hào)的文件打包成zip文件,上傳到服務(wù)器
- 調(diào)用`RUpgrade.upgrade(...,upgradeFlavor:RUpgradeFlavor.hotUpgrade)`方法進(jìn)行下載
- 下載完成后,將上面獲取到的id進(jìn)行熱更新,調(diào)用如下代碼
           bool isSuccess = await RUpgrade.install(id);
           if (isSuccess) {
              _state.currentState
                    .showSnackBar(SnackBar(content: Text('熱更新成功,3s后退出應(yīng)用,請(qǐng)重新進(jìn)入')));
                Future.delayed(Duration(seconds: 3)).then((_){
                  SystemNavigator.pop(animated: true);
                });
           }else{
              _state.currentState
                    .showSnackBar(SnackBar(content: Text('熱更新失敗,請(qǐng)等待更新包下載完成')));
              }
- 重啟應(yīng)用即可

注意:目前熱更新尚處于測(cè)試階段,只支持Flutter代碼的變更,不支持資源文件等,熱更新造成的一切的后果插件的作者概不負(fù)責(zé),由使用者承擔(dān)。

安卓平臺(tái)通知欄

如果你想自定義通知欄顯示的內(nèi)容, 可以這樣做, 修改或添加文件路徑為project/android/app/main/res/r_upgrade_value.xml,添加下面代碼

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="r_upgrade_download_speech">%.2fkb/s</string>
    <string name="r_upgrade_download_planTime">預(yù)計(jì)%.0f秒后完成</string>
    <string name="r_upgrade_download_finish">下載完成</string>
    <string name="r_upgrade_download_paused">下載被暫停</string>
    <string name="r_upgrade_download_failed">下載失敗</string>
</resources>

然后.當(dāng)你使用upgrade方法時(shí),你應(yīng)該設(shè)置參數(shù)notificationStyle,默認(rèn)為顯示預(yù)計(jì)完成時(shí)間.

/// Notification show style about content text
enum NotificationStyle {
  speechAndPlanTime, // 100kb/s 預(yù)計(jì)1秒后完成
  planTimeAndSpeech, // 預(yù)計(jì)1秒后完成 100kb/s
  speech,// 100kb/s
  planTime, // 預(yù)計(jì)1秒后完成
  none, //
}

IOS平臺(tái)

1.跳轉(zhuǎn)到AppStore進(jìn)行更新

    void upgradeFromAppStore() async {
        bool isSuccess =await RUpgrade.upgradeFromAppStore(
                '您的AppId',//例如:微信的AppId:414478124
              );
        print(isSuccess);
    }

2.獲取AppStore中你的應(yīng)用最后的版本名

    void getVersionFromAppStore() async {
        String versionName = await RUpgrade.getVersionFromAppStore(
                '您的AppId',//例如:微信的AppId:414478124
               );
        print(versionName);
    }

結(jié)尾:Dart客棧已經(jīng)推出Aqueduct框架系列教程專(zhuān)輯,歡迎喜歡學(xué)習(xí)Dart語(yǔ)言開(kāi)發(fā)的小伙伴關(guān)注????

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,967評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,273評(píng)論 3 415
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,870評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,742評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,527評(píng)論 6 407
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,010評(píng)論 1 322
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,108評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,250評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,769評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,656評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,853評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,371評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,103評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,472評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,717評(píng)論 1 281
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,487評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,815評(píng)論 2 372