XUpdate 一個輕量級、高可用性的Android版本更新框架

XUpdate

api
I
Star

一個輕量級、高可用性的Android版本更新框架。趕忙點擊使用說明文檔,體驗一下吧!android

在提issue前,請先閱讀【提問的智慧】,並嚴格按照issue模板進行填寫,節約你們的時間。git

在使用前,請必定要仔細閱讀使用說明文檔,重要的事情說三遍!!!github

在使用前,請必定要仔細閱讀使用說明文檔,重要的事情說三遍!!!json

在使用前,請必定要仔細閱讀使用說明文檔,重要的事情說三遍!!!api

關於我

github
csdn
簡書
掘金
知乎

X系列庫快速集成

爲了方便你們快速集成X系列框架庫,我提供了一個空殼模版供你們參考使用: github.com/xuexiangjys…緩存


特色

  • 支持post和get兩種版本檢查方式,支持自定義網絡請求。bash

  • 支持設置只在wifi下進行版本更新。服務器

  • 支持靜默下載(後臺更新)、自動版本更新。網絡

  • 提供界面友好的版本更新提示彈窗,可自定義其主題樣式。app

  • 支持自定義版本更新檢查器、版本更新解析器、版本更新提示器、版本更新下載器、版本更新安裝、出錯處理。

  • 支持MD5文件校驗、版本忽略、版本強制更新等功能。

  • 支持自定義文件校驗方法【默認是MD5校驗】。

  • 支持自定義請求API接口。

  • 兼容Android6.0、7.0、8.0和9.0。

  • 支持中文和英文兩種語言顯示(國際化)

組成結構

本框架借鑑了AppUpdate中的部分思想和UI界面,將版本更新中的各部分環節抽離出來,造成了以下幾個部分:

  • 版本更新檢查器IUpdateChecker:檢查是否有最新版本。

  • 版本更新解析器IUpdateParser:解析服務端返回的數據結果。

  • 版本更新提示器IUpdatePrompter:展現最新的版本信息。

  • 版本更新下載器IUpdateDownloader:下載最新的版本APK安裝包。

  • 網絡請求服務接口IUpdateHttpService:定義了進行網絡請求的相關接口。

除此以外,還有兩個監聽器:

  • 版本更新失敗的監聽器OnUpdateFailureListener

  • 版本更新apk安裝的監聽器OnInstallListener

一、演示(請star支持)

  • 默認版本更新

  • 強制版本更新

  • 自定義提示彈窗主題

  • 使用系統彈窗提示

Demo下載

downloads

二、如何使用

目前支持主流開發工具AndroidStudio的使用,直接配置build.gradle,增長依賴便可.

2.一、Android Studio導入方法,添加Gradle依賴

1.先在項目根目錄的 build.gradle 的 repositories 添加:

allprojects {
     repositories {
        ...
        maven { url "https://jitpack.io" }
    }
}
複製代碼

2.而後在dependencies添加:

dependencies {
  ...
  implementation 'com.github.xuexiangjys:XUpdate:1.1.1'
}
複製代碼

2.二、初始化XUpdate

在Application進行初始化配置:

XUpdate.get()
    .debug(true)
    .isWifiOnly(true)                                               //默認設置只在wifi下檢查版本更新
    .isGet(true)                                                    //默認設置使用get請求檢查版本
    .isAutoMode(false)                                              //默認設置非自動模式,可根據具體使用配置
    .param("versionCode", UpdateUtils.getVersionCode(this))         //設置默認公共請求參數
    .param("appKey", getPackageName())
    .setOnUpdateFailureListener(new OnUpdateFailureListener() {     //設置版本更新出錯的監聽
        @Override
        public void onFailure(UpdateError error) {
            if (error.getCode() != CHECK_NO_NEW_VERSION) {          //對不一樣錯誤進行處理
                ToastUtils.toast(error.toString());
            }
        }
    })
    .supportSilentInstall(true)                                     //設置是否支持靜默安裝,默認是true
    .setIUpdateHttpService(new OKHttpUpdateHttpService())           //這個必須設置!實現網絡請求功能。
    .init(this);                                                    //這個必須初始化
複製代碼

【注意】:若是出現任何問題,可開啓debug模式來追蹤問題。若是你還須要將日誌記錄在磁盤上,可實現如下接口

XUpdate.get().setILogger(new ILogger() {
    @Override
    public void log(int priority, String tag, String message, Throwable t) {
        //實現日誌記錄功能
    }
});
複製代碼

2.三、版本更新實體信息

(1) UpdateEntity字段屬性

字段名 類型 默認值 備註
mHasUpdate boolean false 是否有新版本
mIsForce boolean false 是否強制安裝:不安裝沒法使用app
mIsIgnorable boolean false 是否可忽略該版本
mVersionCode int 0 最新版本code
mVersionName String unknown_version 最新版本名稱
mUpdateContent String "" 更新內容
mDownloadEntity DownloadEntity 下載信息實體
mIsSilent boolean false 是否靜默下載:有新版本時不提示直接下載
mIsAutoInstall boolean true 是否下載完成後自動安裝

(2) DownloadEntity字段屬性

字段名 類型 默認值 備註
mDownloadUrl String "" 下載地址
mCacheDir String "" 文件下載的目錄
mMd5 String "" 下載文件的加密校驗值(默認使用md5加密),用於校驗,防止下載的apk文件被替換(最新演示demo中有計算校驗值的工具)
mSize long 0 下載文件的大小【單位:KB】
mIsShowNotification boolean false 是否在通知欄上顯示下載進度

2.四、文件加密校驗方式

本框架默認使用的文件加密校驗方法是MD5加密方式,固然若是你不想使用MD5加密,你也能夠自定義文件加密器IFileEncryptor,如下是MD5文件加密器的實現供參考:

/**
 * 默認的文件加密計算使用的是MD5加密
 *
 * @author xuexiang
 * @since 2019-09-06 14:21
 */
public class DefaultFileEncryptor implements IFileEncryptor {
    /**
     * 加密文件
     *
     * @param file
     * @return
     */
    @Override
    public String encryptFile(File file) {
        return Md5Utils.getFileMD5(file);
    }

    /**
     * 檢驗文件是否有效(加密是否一致)
     *
     * @param encrypt 加密值, 若是encrypt爲空,直接認爲是有效的
     * @param file    須要校驗的文件
     * @return 文件是否有效
     */
    @Override
    public boolean isFileValid(String encrypt, File file) {
        return TextUtils.isEmpty(encrypt) || encrypt.equalsIgnoreCase(encryptFile(file));
    }
}

複製代碼

最後再調用XUpdate.get().setIFileEncryptor方法設置便可生效。

三、版本更新

3.一、默認版本更新

直接調用以下代碼便可完成版本更新操做:

XUpdate.newBuild(getActivity())
        .updateUrl(mUpdateUrl)
        .update();
複製代碼

須要注意的是,使用默認版本更新,請求服務器返回的json格式應包括以下內容:

{
  "Code": 0,
  "Msg": "",
  "UpdateStatus": 1,
  "VersionCode": 3,
  "VersionName": "1.0.2",
  "ModifyContent": "一、優化api接口。\r\n二、添加使用demo演示。\r\n三、新增自定義更新服務API接口。\r\n四、優化更新提示界面。",
  "DownloadUrl": "https://raw.githubusercontent.com/xuexiangjys/XUpdate/master/apk/xupdate_demo_1.0.2.apk",
  "ApkSize": 2048
  "ApkMd5": "..."  //md5值沒有的話,就沒法保證apk是否完整,每次都會從新下載。
}
複製代碼

3.二、自動版本更新

自動版本更新:自動檢查版本 + 自動下載apk + 自動安裝apk(靜默安裝)。 只須要設置isAutoMode(true),不過若是設備沒有root權限的話,是沒法作到徹底的自動更新(由於靜默安裝須要root權限)。

XUpdate.newBuild(getActivity())
        .updateUrl(mUpdateUrl)
        .isAutoMode(true) //若是須要徹底無人干預,自動更新,須要root權限【靜默安裝須要】
        .update();
複製代碼

3.三、強制版本更新

就是用戶不更新的話,程序將沒法正常使用。只須要服務端返回UpdateStatus字段爲2便可。

固然若是你自定義請求返回api的話,只須要設置UpdateEntitymIsForce字段爲true便可。

3.四、自定義版本更新提示彈窗的主題

可設置彈窗的標題背景和按鈕顏色。

  • themeColor: 設置主題顏色(升級/安裝按鈕的背景色)
  • topResId: 彈窗的標題背景的資源圖片
XUpdate.newBuild(getActivity())
        .updateUrl(mUpdateUrl)
        .themeColor(ResUtils.getColor(R.color.update_theme_color))
        .topResId(R.mipmap.bg_update_top)
        .update();
複製代碼

3.五、自定義版本更新解析器

實現IUpdateParser接口便可實現解析器的自定義。

XUpdate.newBuild(getActivity())
        .updateUrl(mUpdateUrl3)
        .updateParser(new CustomUpdateParser()) //設置自定義的版本更新解析器
        .update();

public class CustomUpdateParser implements IUpdateParser {
    @Override
    public UpdateEntity parseJson(String json) throws Exception {
        CustomResult result = JsonUtil.fromJson(json, CustomResult.class);
        if (result != null) {
            return new UpdateEntity()
                    .setHasUpdate(result.hasUpdate)
                    .setIsIgnorable(result.isIgnorable)
                    .setVersionCode(result.versionCode)
                    .setVersionName(result.versionName)
                    .setUpdateContent(result.updateLog)
                    .setDownloadUrl(result.apkUrl)
                    .setSize(result.apkSize);
        }
        return null;
    }
}

複製代碼

3.六、自定義版本更新檢查器+版本更新解析器+版本更新提示器

  • 實現IUpdateChecker接口便可實現檢查器的自定義。

  • 實現IUpdateParser接口便可實現解析器的自定義。

  • 實現IUpdatePrompter接口便可實現提示器的自定義。

XUpdate.newBuild(getActivity())
        .updateUrl(mUpdateUrl3)
        .updateChecker(new DefaultUpdateChecker() {
            @Override
            public void onBeforeCheck() {
                super.onBeforeCheck();
                CProgressDialogUtils.showProgressDialog(getActivity(), "查詢中...");
            }
            @Override
            public void onAfterCheck() {
                super.onAfterCheck();
                CProgressDialogUtils.cancelProgressDialog(getActivity());
            }
        })
        .updateParser(new CustomUpdateParser())
        .updatePrompter(new CustomUpdatePrompter(getActivity()))
        .update();


public class CustomUpdatePrompter implements IUpdatePrompter {

    private Context mContext;

    public CustomUpdatePrompter(Context context) {
        mContext = context;
    }

    @Override
    public void showPrompt(@NonNull UpdateEntity updateEntity, @NonNull IUpdateProxy updateProxy) {
        showUpdatePrompt(updateEntity, updateProxy);
    }

    /**
     * 顯示自定義提示
     *
     * @param updateEntity
     * @param updateProxy
     */
    private void showUpdatePrompt(final @NonNull UpdateEntity updateEntity, final @NonNull IUpdateProxy updateProxy) {
        String updateInfo = UpdateUtils.getDisplayUpdateInfo(updateEntity);

        new AlertDialog.Builder(mContext)
                .setTitle(String.format("是否升級到%s版本?", updateEntity.getVersionName()))
                .setMessage(updateInfo)
                .setPositiveButton("升級", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        updateProxy.startDownload(updateEntity, new OnFileDownloadListener() {
                            @Override
                            public void onStart() {
                                HProgressDialogUtils.showHorizontalProgressDialog(mContext, "下載進度", false);
                            }

                            @Override
                            public void onProgress(float progress, long total) {
                                HProgressDialogUtils.setProgress(Math.round(progress * 100));
                            }

                            @Override
                            public boolean onCompleted(File file) {
                                HProgressDialogUtils.cancel();
                                return true;
                            }

                            @Override
                            public void onError(Throwable throwable) {
                                HProgressDialogUtils.cancel();
                            }
                        });
                    }
                })
                .setNegativeButton("暫不升級", null)
                .setCancelable(false)
                .create()
                .show();
    }
複製代碼

3.七、只使用XUpdate的下載器功能進行apk的下載

XUpdate.newBuild(getActivity())
        .apkCacheDir(PathUtils.getExtDownloadsPath()) //設置下載緩存的根目錄
        .build()
        .download(mDownloadUrl, new OnFileDownloadListener() {   //設置下載的地址和下載的監聽
            @Override
            public void onStart() {
                HProgressDialogUtils.showHorizontalProgressDialog(getContext(), "下載進度", false);
            }

            @Override
            public void onProgress(float progress, long total) {
                HProgressDialogUtils.setProgress(Math.round(progress * 100));
            }

            @Override
            public boolean onCompleted(File file) {
                HProgressDialogUtils.cancel();
                ToastUtils.toast("apk下載完畢,文件路徑:" + file.getPath());
                return false;
            }

            @Override
            public void onError(Throwable throwable) {
                HProgressDialogUtils.cancel();
            }
        });
複製代碼

3.八、只使用XUpdate的APK安裝的功能

_XUpdate.startInstallApk(getContext(), FileUtils.getFileByPath(PathUtils.getFilePathByUri(getContext(), data.getData()))); //填寫文件所在的路徑
複製代碼

若是你的apk安裝不同凡響,你能夠實現本身的apk安裝器。你只須要實現OnInstallListener接口,並經過XUpdate.setOnInstallListener進行設置便可生效。

混淆配置

-keep class com.xuexiang.xupdate.entity.** { *; }
複製代碼

特別感謝

github.com/WVector/App…

聯繫方式

相關文章
相關標籤/搜索