Android实现App增量更新代码实现。

news2024/11/19 13:35:47

一、增量更新实现思路

   1)服务端生成patch差分包:

         值得注意的是,需要对用户安装的不同版本,生成不同的差分包,为了是让用户安装的所有版本都升级为最新的版本。

   2)客户端请求差分包:

         客户端在请求的时候,会把客户端的版本发送给服务端,服务端根据不同的版本,下发不同的差分包。

   3)客户端合成新的安装包:

          客户端通过调用native代码,将安装的包和下载的差分包生成新的安装包。这时需要对生成的安装包进行md5校验,保证生成的和最新的包是一样的。

二、服务端生成差分包的方法

      通过bsdiff命令生成差分包:bsdiff old.apk new.apk patch.apk

       old.apk是原apk路径,new.apk目前apk路径,patch.apk是生成的差分包的文件路径。

       命令下载:https://download.csdn.net/download/niuyongzhi/88366198?spm=1001.2014.3001.5501

执行命令:

生成的文件:

三、客户端生成新的安装包

        在没有服务端的情况下,客户端测试,可以把生成的patch包拷贝到sdcard目录下,当做是已经从服务端下载好的patch包。

        客户端调用native代码:

public static native int patch(String oldApkPath, String newApkPath,
			String patchPath);

     1)oldApkpath:安装在手机中的Apk包,可以通过一下代码获取。

     2)newApkPath:即合成新的Apk后的路径。

     3)patchPath:存放在sdcard的差分包路径。

  /**
     * 获取已安装Apk路径
     * packageName 报名
     */
    public static String getOldApkPath(Context context, String packageName) {
        if (TextUtils.isEmpty(packageName))
            return null;

        try {
            ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(packageName, 0);
            return appInfo.sourceDir;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        return null;
    }

   4)新的安装包生成后,进行md5校验,校验通过调用安装apk代码:

MD5校验代码:

private static String bytes2Hex(byte[] src) {
		char[] res = new char[src.length * 2];
		final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
		for (int i = 0, j = 0; i < src.length; i++) {
			res[j++] = hexDigits[src[i] >>> 4 & 0x0f];
			res[j++] = hexDigits[src[i] & 0x0f];
		}

		return new String(res);
	}

	public static String getMd5ByFile(File file) {
		String value = null;
		FileInputStream in = null;
		try {
			in = new FileInputStream(file);

			MessageDigest digester = MessageDigest.getInstance("MD5");
			byte[] bytes = new byte[8192];
			int byteCount;
			while ((byteCount = in.read(bytes)) > 0) {
				digester.update(bytes, 0, byteCount);
			}
			value = bytes2Hex(digester.digest());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != in) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return value;
	}

调用系统api进行新包安装:

 public static void installApk(Context context, File file) {
        boolean canInstall = true;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            canInstall = context.getPackageManager().canRequestPackageInstalls();
        }
        if (canInstall) {
            Uri uri;
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            if (Build.VERSION.SDK_INT >= 24) {
                uri = FileProvider.getUriForFile(context, "com.example.patch.fileProvider", file);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            } else {
                uri = Uri.fromFile(file);

            }
            intent.setDataAndType(uri, "application/vnd.android.package-archive");
            context.startActivity(intent);

        } else {
            context.startActivity(new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES));
        }
    }

这时,就完成了apk增量升级。

四:客户端编译native代码生成so库,供java端进行新版合成的进行调用。

  1)File->New->New Module 选择Android Native Library,创建一个Native module项目。

  2)将bip2的c层代码拷贝到cpp目录下。

3)配置CMakeLists.txt。红色框的代码是要编译的代码。绿色框中apk_pacth是编译后生成的so库的名字。

 

4)java层创建Native方法

public class PatchUtils {

	public static native int patch(String oldApkPath, String newApkPath,
			String patchPath);
}

5)Android Studio会自动提示生成JNI层对应的方法。如果没有,通过javac -h 或javah生成头文件。

javac -h 生成的头文件命令由三部分组成:

1)javac -h

2) 生成的头文件存放的路径

3)要生成头文件Native方法所在java类的路径。

命令执行会生成一个class文件和一个.h文件。

头文件长这个样子:

 4)编写JNI层代码。JNI大家都不陌生,他是连接Java和Native的桥梁。


/*
 * Class:     com_example_utils_PatchUtils
 * Method:    patch
 * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_com_example_utils_PatchUtils_patch(JNIEnv *env,
                                                               jclass obj, jstring old, jstring new, jstring patch) {

    char * ch[4];
    ch[0] = "bspatch";
    ch[1] = (char*) ((*env)->GetStringUTFChars(env, old, 0));
    ch[2] = (char*) ((*env)->GetStringUTFChars(env, new, 0));
    ch[3] = (char*) ((*env)->GetStringUTFChars(env, patch, 0));

    __android_log_print(ANDROID_LOG_INFO, "ApkPatchLibrary", "old = %s ", ch[1]);
    __android_log_print(ANDROID_LOG_INFO, "ApkPatchLibrary", "new = %s ", ch[2]);
    __android_log_print(ANDROID_LOG_INFO, "ApkPatchLibrary", "patch = %s ", ch[3]);

    int ret = applypatch(4, ch);

    __android_log_print(ANDROID_LOG_INFO, "ApkPatchLibrary", "applypatch result = %d ", ret);

    (*env)->ReleaseStringUTFChars(env, old, ch[1]);
    (*env)->ReleaseStringUTFChars(env, new, ch[2]);
    (*env)->ReleaseStringUTFChars(env, patch, ch[3]);

    return ret;
}

bsdiff命令下载地址:https://download.csdn.net/download/niuyongzhi/88366198

代码下载地址:https://download.csdn.net/download/niuyongzhi/88374161

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1039425.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小样本规模船型优化策略的选择研究

天洑软件基于自研智能优化软件AIPOD在船舶行业的应用发表论文《小样本规模船型优化策略的选择研究》刊录于核心期刊《中国造船》。全文如下&#xff1a; 小样本规模船型优化策略的选择研究 陈骏喆&#xff0c;姜 栋&#xff0c;张 儒&#xff0c;张 明 &#xff08;南京天洑…

PIP安装

首先进入这个网站 https://pypi.org/project/pip/#files 选择如图所示的安装包 解压刚才下载的pip安装包打开cmd&#xff08; 使用winR 输入cmd&#xff09; 如图切换到pip文件夹下面 输入python setup.py install 按enter回车键

翻译像机翻?4点教会你ChatGPT高质量翻译

如果完全靠自己的英文和中文水平&#xff0c;要达到这样的翻译速度和质量那是不太可能的&#xff0c;主要还是得益于ChatGPT的帮助&#xff0c;首先用GPT-4的API粗翻&#xff0c;再用ChatGPT Plus精翻。很多人都用过ChatGPT翻译&#xff0c;但翻译出来的结果比起Google翻译和De…

排序:插入排序算法分析以及相关优化(折半插入排序)

1.算法思想︰ 每次将一个待排序的记录按其关键字大小插入到前面已排好序的子序列中&#xff0c;直到全部记录插入完成。 直接插入排序:顺序查找找到插入的位置&#xff0c;适用于顺序表、链表。 2.算法实现 //直接插入排序 void InsertSort(int A[], int n) {int i, j, tem…

12.InnoDB记录结构

title: “InnoDB记录结构” createTime: 2022-03-06T15:52:4108:00 updateTime: 2022-03-06T15:52:4108:00 draft: false author: “ggball” tags: [“mysql”] categories: [“db”] description: “” InnoDB记录结构 innoDB存储引擎介绍 存储引擎的作用就是内存和磁盘打…

python随手小练2

题目&#xff1a; 今有物不知其数&#xff0c;三三数之剩二&#xff0c;五五数之剩三&#xff0c;七七数之剩二&#xff0c;为何&#xff1f; &#xff08;即&#xff1a;一个数除3余2&#xff0c;除5余3&#xff0c;除7余2&#xff09; 具体操作&#xff1a; xint(input(&quo…

AI编写文案工具哪些好用且免费

什么是AI编写文案工具&#xff1f;AI编写文案工具基于自然语言处理技术的应用程序&#xff0c;它们旨在协助用户创建各种类型的文案&#xff0c;从广告、营销材料到新闻稿和博客文章&#xff0c;都可以得心应手。这种技术的崛起源于对写作效率和质量的不断追求。 AI编写文案工具…

做销售管理分析需要看哪些关键指标?

做销售管理分析需要看哪些关键指标&#xff1f; 销售管理分析时抓取关键指标&#xff0c;有着能够【分析和判断销售趋势、为销售决策提供数据支持、优化销售流程和客户管理】等的好处 在了解了分析关键指标的目的之后&#xff0c;我们就可以根据企业的需求来确定关键指标&…

淘宝/天猫获得店铺的所有商品 API 返回值说明

淘宝API接口是为开发电商类应用程序而设计的一套完整的、跨浏览器、跨平台的接口规范。 通过开放接口&#xff0c;开发者可以不改变现有系统&#xff0c;直接在原有系统上实现新功能。 在开发过程中&#xff0c;使用淘宝API接口可以帮助开发者快速搭建自己的应用&#xff0c;实…

2023年Java毕业设计题目如何选题?Java毕业设计选题大全

大家好&#xff0c;我是程序员徐师兄&#xff0c;最近有很多同学咨询&#xff0c;说毕业设计了&#xff0c;不知道选怎么题目好&#xff0c;有哪些是想需要注意的。 确实毕设选题实际上对很多同学来说一个大坑&#xff0c; 每年挖坑给自己跳的人太多太多。选到合适的题目的话&…

Linux字符设备驱动开发

文章目录 字符设备简单介绍file_operations结构体驱动编译为模块字符设备注册与注销设备的操作函数初始化添加LICENSE和作者信息设备号的分配文件操作函数字符设备驱动示例源文件chrdev.cMakefile文件测试代码app.c编译开发板上验证 字符设备简单介绍 字符设备是Linux驱动中最…

Lua函数

--函数--无参无返回值 function F1()print("F1函数") end F1() print("*****************")--有参 function F2(a)print("F2函数"..a) end F2(2) --如果传入参数和函数数量不一致 --不会报错只是补空 F2(1,2) print("*****************&quo…

iOS应用程序的签名、重签名和安装测试

目录 前言 打开要处理的IPA文件 设置签名使用的证书和描述文件 开始ios ipa重签名 前言 ipa编译出来后&#xff0c;或者ipa进行修改后&#xff0c;需要进行重新签名才能安装到测试手机&#xff0c;或者提交app store供apple 商店审核上架。ipaguard有签名和重签名功能&…

9.21广读最新arxiv论文 思路学习汇总

Towards Generative Modeling of Urban Flow through Knowledge-enhanced Denoising Diffusion 摘要&#xff1a;尽管生成式人工智能在许多领域取得了成功&#xff0c;但在建模地理空间数据方面的潜力仍尚未充分发掘。城市流动&#xff0c;是一种典型的地理空间数据&#xff0c…

单列集合顶层接口Collection

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaEE 操作系统 Redis 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 集合体系结构 一、单列集合顶层接口Collect…

机器学习小白理解之一元线性回归

关于机器学习&#xff0c;百度上一搜一大摞&#xff0c;总之各有各的优劣&#xff0c;有的非常专业&#xff0c;有的看的似懂非懂。我作为一名机器学习的门外汉&#xff0c;为了看懂这些公式和名词真的花了不少时间&#xff0c;还因此去着重学了高数。 不过如果不去看公式&…

软件推荐:wiztree

简要介绍 近期C盘占满&#xff0c;找到了这款优秀的软件wiztree。 wiztree称得上最快的磁盘空间分析器&#xff0c;界面简洁明晰&#xff0c;操作简单快捷&#xff0c;无广告。 下载地址&#xff1a;https://www.diskanalyzer.com/download 软件截图

Opencv cuda版本在ubuntu22.04中安装办法,解决Could NOT find CUDNN的办法

文章目录 概要下载cuda的runfile版本配置环境变量官网下载cudann安装Opencv依赖包下载opencv和opencv_contrib并解压准备编译安装anaconda环境执行编译命令安装OpenCV并检查是否安装成功 概要 解决以下安装问题&#xff1a; -- Could NOT find CUDNN: Found unsuitable versi…

OpenCascade绘制贝塞尔曲线

贝塞尔曲线有着很多特殊的性质, 在图形设计和路径规划中应用都非常广泛。 贝塞尔曲线完全由其控制点决定其形状, &#xff4e;个控制点对应着&#xff4e;&#xff0d;&#xff11;阶的贝塞尔曲线&#xff0c;并且可以通过递归的方式来绘制。 一阶: 二阶: 高阶&#xff1a; …

雷士、书客、小米的护眼台灯谁的性价比最高?三款护眼台灯真实测评

护眼台灯怎么选一直是许多家长为孩子选台灯时的一个大难题&#xff0c;主要因为市场上的台灯种类太多&#xff0c;而且这些产品中混杂了许多不专业品牌&#xff0c;甚至包括许多劣质台灯和网红品牌&#xff01;同时也经常能够看到报道很多“抽检不合格”的情况发生&#xff0c;…