• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

XUpdate: 一个轻量级、高可用性的Android版本更新框架

原作者: [db:作者] 来自: 网络 收藏 邀请

开源软件名称:

XUpdate

开源软件地址:

https://gitee.com/xuexiangjys/XUpdate

开源软件介绍:

XUpdate

apiIStar

英文 | 中文视频教程

一个轻量级、高可用性的Android版本更新框架。赶紧点击使用说明文档,体验一下吧!

在提issue前,请先阅读【提问的智慧】,并严格按照issue模板进行填写,节约大家的时间。

在使用前,请一定要仔细阅读使用说明文档,重要的事情说三遍!!!

在使用前,请一定要仔细阅读使用说明文档,重要的事情说三遍!!!

在使用前,请一定要仔细阅读使用说明文档,重要的事情说三遍!!!

关于我

公众号掘金知乎CSDN简书思否哔哩哔哩今日头条
我的Android开源之旅点我点我点我点我点我点我点我

简化使用

想要更快地使用XUpdate,降低集成的难度,支持断点续传下载等拓展功能,可以尝试使用XUpdateAPI.

X系列库快速集成

为了方便大家快速集成X系列框架库,我提供了一个空壳模版供大家参考使用: https://github.com/xuexiangjys/TemplateAppProject


特征

  • 支持post和get两种版本检查方式,支持自定义网络请求。

  • 支持设置只在wifi下进行版本更新。

  • 支持静默下载(后台更新)、自动版本更新。

  • 提供界面友好的版本更新提示弹窗,可自定义其主题样式。

  • 支持自定义版本更新检查器、版本更新解析器、版本更新提示器、版本更新下载器、版本更新安装、出错处理。

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

  • 支持自定义文件校验方法【默认是MD5校验】。

  • 支持自定义请求API接口。

  • 兼容Android6.0~11.0。

  • 支持中文和英文两种语言显示(国际化)。

  • 支持Flutter插件使用:flutter_xupdate

  • 支持React-Native插件使用:react-native-xupdate

Star趋势图

Stargazers over time

组成结构

本框架借鉴了AppUpdate中的部分思想和UI界面,将版本更新中的各部分环节抽离出来,形成了如下几个部分:

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

  • 版本更新解析器IUpdateParser:解析服务端返回的数据结果。

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

  • 版本更新下载器IUpdateDownloader:下载最新的版本APK安装包。

  • 网络请求服务接口IUpdateHttpService:定义了进行网络请求的相关接口。

除此之外,还有两个监听器:

  • 版本更新失败的监听器OnUpdateFailureListener

  • 版本更新apk安装的监听器OnInstallListener

更新调度核心:

  • 版本更新业务代理IUpdateProxy:负责版本更新的流程控制,调用update开始进行版本更新流程。

更新流程

调用update之后的流程:

IUpdateProxy/XUpdate --- (update) ---> IUpdateChecker --->(请求服务器,获取最新版本信息)---> IUpdateParser ---> (解析服务器返回的数据,并构建UpdateEntity版本更新实体)---> IUpdateProxy ---> (如无最新版本,直接结束,否则进行下面流程)    ---自动模式---> IUpdateDownloader ---> (下载最新的应用apk) ---> 安装应用    ---非自动模式---> IUpdatePrompter ---> 给出版本更新的提示                                                        ---> 用户点击更新 ---> IUpdateDownloader ---> (下载最新的应用apk) ---> 跳转到应用安装界面                                                        ---> 用户点击(取消或忽略) ---> 结束

点击查看框架UML设计图


1、演示(请star支持)

  • 默认版本更新

xupdate_default.png

  • 后台更新

xupdate_background.png

  • 强制版本更新

xupdate_force.png

  • 可忽略版本更新

xupdate_ignore.png

  • 自定义提示弹窗主题

xupdate_custom.png

  • 使用系统弹窗提示

xupdate_system.png

Demo更新后台服务

由于github最近访问比较慢,如果需要更好地体验XUpdate,你可以点击自己搭建一个简易的版本更新服务

Demo下载

蒲公英下载

蒲公英下载的密码: xuexiangjys

downloads

xupdate_download_pugongying.png

Github下载

downloads

xupdate_download.png


2、快速集成指南

目前支持主流开发工具AndroidStudio的使用,直接配置build.gradle,增加依赖即可.

2.1、Android Studio导入方法,添加Gradle依赖

1.先在项目根目录的 build.gradle 的 repositories 添加:

allprojects {     repositories {        ...        maven { url "https://jitpack.io" }    }}

2.然后在dependencies添加:

以下是版本说明,选择一个即可。

  • androidx版本:2.0.0及以上
dependencies {  ...  // androidx版本  implementation 'com.github.xuexiangjys:XUpdate:2.1.1'}
  • support版本:1.1.6及以下
dependencies {  ...  // support版本  implementation 'com.github.xuexiangjys:XUpdate:1.1.6'}

2.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.3、版本更新实体信息

(1) UpdateEntity字段属性

字段名类型默认值备注
mHasUpdatebooleanfalse是否有新版本
mIsForcebooleanfalse是否强制安装:不安装无法使用app
mIsIgnorablebooleanfalse是否可忽略该版本
mVersionCodeint0最新版本code
mVersionNameStringunknown_version最新版本名称
mUpdateContentString""更新内容
mDownloadEntityDownloadEntity下载信息实体
mIsSilentbooleanfalse是否静默下载:有新版本时不提示直接下载
mIsAutoInstallbooleantrue是否下载完成后自动安装

(2) DownloadEntity字段属性

字段名类型默认值备注
mDownloadUrlString""下载地址
mCacheDirString""文件下载的目录
mMd5String""下载文件的加密校验值(默认使用md5加密),用于校验,防止下载的apk文件被替换(最新演示demo中有计算校验值的工具),注意这里的md5值非应用签名文件的md5值!
mSizelong0下载文件的大小【单位:KB】
mIsShowNotificationbooleanfalse是否在通知栏上显示下载进度

(3) PromptEntity字段属性

字段名类型默认值备注
mThemeColorintR.color.xupdate_default_theme_color主题色(进度条和按钮的背景色)
mTopResIdintR.drawable.xupdate_bg_app_top顶部背景图片资源id
mTopDrawableTagString""顶部背景图片Drawable标识
mButtonTextColorint0按钮文字颜色
mSupportBackgroundUpdatebooleanfalse是否支持后台更新
mWidthRatiofloat-1(无约束)版本更新提示器宽度占屏幕的比例
mHeightRatiofloat-1(无约束)版本更新提示器高度占屏幕的比例
mIgnoreDownloadErrorbooleanfalse是否忽略下载异常(下载失败更新提示框不消失)

2.4、文件加密校验方式

本框架默认使用的文件加密校验方法是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、版本更新

3.1、默认版本更新

直接调用如下代码即可完成版本更新操作:

XUpdate.newBuild(getActivity())        .updateUrl(mUpdateUrl)        .update();

需要注意的是,使用默认版本更新,请求服务器返回的json格式应包括如下内容:

{  "Code": 0,  "Msg": "",  "UpdateStatus": 1,  "VersionCode": 3,  "VersionName": "1.0.2",  "ModifyContent": "1、优化api接口。\r\n2、添加使用demo演示。\r\n3、新增自定义更新服务API接口。\r\n4、优化更新提示界面。",  "DownloadUrl": "https://raw.githubusercontent.com/xuexiangjys/XUpdate/master/apk/xupdate_demo_1.0.2.apk",  "ApkSize": 2048,  "ApkMd5": ""}

字段说明:

  • Code: 0代表请求成功,非0代表失败。
  • Msg: 请求出错的信息。
  • UpdateStatus: 版本更新状态。0代表不更新,1代表有版本更新,不需要强制升级,2代表有版本更新,需要强制升级。
  • VersionCode: 版本号,自增。本地会用于比较版本是否为最新版本。
  • VersionName: 版本的展示名称。
  • ModifyContent: 版本更新的内容。
  • DownloadUrl: 应用apk文件的下载地址。
  • ApkSize: 应用apk文件的文件大小,单位是KB。
  • ApkMd5: 应用apk文件的MD5值。如果没有的话,将无法保证apk是否完整,每次都会重新下载。框架默认使用的是MD5加密。

3.2、自动版本更新

自动版本更新:自动检查版本 + 自动下载apk + 自动安装apk(静默安装)。只需要设置isAutoMode(true),不过如果设备没有root权限的话,是无法做到完全的自动更新(因为静默安装需要root权限)。

XUpdate.newBuild(getActivity())        .updateUrl(mUpdateUrl)        .isAutoMode(true) //如果需要完全无人干预,自动更新,需要root权限【静默安装需要】        .update();

3.3、支持后台更新

开启支持后台更新后, 用户点击“后台更新”按钮后,就可以进入到后台更新,不用一直在更新界面等待.

XUpdate.newBuild(getActivity())        .updateUrl(mUpdateUrl)        .supportBackgroundUpdate(true)        .update();

3.4、强制版本更新

就是用户不更新的话,程序将无法正常使用。只需要服务端返回UpdateStatus字段为2即可。

当然如果你自定义请求返回api的话,只需要设置UpdateEntitymIsForce字段为true即可。

3.5、自定义版本更新提示弹窗的主题

通过设置更新顶部图片、主题色、按钮文字颜色、宽高比率等来实现自定义主题样式.

  • promptThemeColor: 设置主题颜色
  • promptButtonTextColor: 设置按钮的文字颜色
  • promptTopResId: 设置顶部背景图片资源ID
  • promptTopDrawable: 设置顶部背景图片
  • promptTopBitmap: 设置顶部背景图片
  • promptWidthRatio: 设置版本更新提示器宽度占屏幕的比例,默认是-1,不做约束
  • promptHeightRatio: 设置版本更新提示器高度占屏幕的比例,默认是-1,不做约束
XUpdate.newBuild(getActivity())        .updateUrl(mUpdateUrl)        .promptThemeColor(ResUtils.getColor(R.color.update_theme_color))        .promptButtonTextColor(Color.WHITE)        .promptTopResId(R.mipmap.bg_update_top)        .promptWidthRatio(0.7F)        .update();

3.6、自定义版本更新解析器

实现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.7、自定义版本更新检查器+版本更新解析器+版本更新提示器

  • 实现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, @NonNull PromptEntity promptEntity) {        showUpdatePrompt(updateEntity, updateProxy);    }    /**     * 显示自定义提示     *     * @param updateEntity     * @param updateProxy     */    private void showUpdatePrompt(final @NonNull UpdateEntity updateEntity, final @NonNull IUpdateProxy updateProxy) {        String updateInfo = UpdateUtils.getDisplayUpdateInfo(mContext, 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.8、只使用XUpdate的下载器功能进行apk的下载

XUpdate.newBuild(getActivity())        .apkCacheDir(PathUtils.getAppExtCachePath()) //设置下载缓存的根目录        .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.9、只使用XUpdate的APK安装的功能

_XUpdate.startInstallApk(getContext(), FileUtils.getFileByPath(PathUtils.getFilePathByUri(getContext(), data.getData()))); //填写文件所在的路径

如果你的apk安装与众不同,你可以实现自己的apk安装器。你只需要实现OnInstallListener接口,并通过XUpdate.setOnInstallListener进行设置即可生效。

3.10、国际化配置

由于作者水平有限, 目前只支持中文和英文两种语言的显示【默认语言是英语】。需要支持其他语言的,只需要在自己项目的res下新建对应的语言文件,进行多语言的翻译即可。

需要翻译的详细内容参见 xupdate_strings.xml 文件。

什么?你还不会Android的多语言配置?建议你看一下这篇文章:Android项目国际化多国语言适配

混淆配置

-keep class com.xuexiang.xupdate.entity.** { *; }//注意,如果你使用的是自定义Api解析器解析,还需要给你自定义Api实体配上混淆,如下是本demo中配置的自定义Api实体混淆规则:-keep class com.xuexiang.xupdatedemo.entity.** { *; }

相关链接


特别感谢

https://github.com/WVector/AppUpdate

如果觉得项目还不错,可以考虑打赏一波

你的打赏是我维护的动力,我将会列出所有打赏人员的清单在下方作为凭证,打赏前请留下打赏项目的备注!

pay.png

感谢下面小伙伴的打赏:

姓名金额方式
*天100¥微信
*航10¥支付宝
X*?18.88¥微信
*网1¥微信
Joe88.88¥微信

公众号

更多资讯内容,欢迎扫描关注我的个人微信公众号:【我的Android开源之旅】

联系方式

xupdate_qq.jpg


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap