增量跟新,这个词相信大家都听说过,有些人也会增量跟新理解为是热跟新,其实不是,增量跟新比热跟新还要重量级一点,需要用户安装,只是下载不是高版本app的资源包,而是下载高版本app跟现版本的app的差分包,一般大小在几百K到几M之间。

增量跟新与全量跟新具有哪些优势?

主要优势:减少用户的跟新下载流量,达到轻量级跟新效果,想一想如果王者荣耀没跟新一点点就下载一个这个大的包,得多浪费流量啊,用户体验也不好。

先讲一下这个大概的流程:

客户端—–>向服务器索取升级信息——>服务器生成差分包——>客户端获取差分包—>合成新的app

服务器:

这里可以调用bspatch里面的main函数就可以生成一个.patch文件,这个就是差分包

在源代码里面bspatch的main函数有2个参数,一个int的argc,一个char*指针数组,如果你直接双击就会退出
所以我们要用cmd执行

输入以上就可以生成差分包,如果是服务器的话,需要下载bspatch的so库,然后用jni调用生成,这里暂时只讲安卓端的,服务器的先略过了哈

现在我们假如apk.patch的路径为http://192.168.1.100/apk.patch

客户端:

Android端:我们拿到bspatch的源码在visuaStudio小小修改一下,把重要的几个C文件copy到app目录当中
这里就不讲这个过程了


MainActivity:

 private static String TAG = "Activity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);if (ApkUtils.getVersionCode(this ,getPackageName()) < 2.0){Log.i(TAG , "不是最新的版本号! 开始更新!");new ApkUpdateTask().execute();} else {Log.i(TAG , "最新版本号 无需更新!");}}class ApkUpdateTask extends AsyncTask<Void ,Void ,Boolean>{@Overrideprotected Boolean doInBackground(Void... voids) {Log.i(TAG , "开始下载...");File patchFile = DownLoadUtils.download(Constants.URL_PATCH_DOWNLOAD);Log.i(TAG , "下载完成......");String oldFile = ApkUtils.getSourceApkPath(MainActivity.this , getPackageName());String newFile = Constants.NEW_APK_PATH;String patchFileString = patchFile.getAbsolutePath();Log.i(TAG , "开始合并");int ret = BsPatch.patch(oldFile , newFile , patchFileString);Log.i(TAG , "合并完成......");if(ret == 0) {return true;} else {return false;}}@Overrideprotected void onPostExecute(Boolean aBoolean) {super.onPostExecute(aBoolean);if (aBoolean){Log.i(TAG , "合并成功 开始安装新APK");ApkUtils.installApk(MainActivity.this , Constants.NEW_APK_PATH);}}}

BsPatch:

    /*** 合并* @param oldFlie* @param newFile* @param patchFlie* @return*/public native static int patch(String oldFlie , String newFile ,String patchFlie);static {System.loadLibrary("JasonBsPatch");}

ApkUtils:

 //获取APK版本号 在公司实际开发中 是根据 key uuid判断(渠道 版本)public static int getVersionCode (Context context, String packageName) {PackageManager pm = context.getPackageManager();try {PackageInfo info = pm.getPackageInfo(packageName, 0);return info.versionCode;} catch (PackageManager.NameNotFoundException e) {e.printStackTrace();return 0;}}/*** 获取已安装Apk文件的源Apk文件* 如:/data/app/my.apk** @param context* @param packageName* @return*/public static String getSourceApkPath(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;}/*** 安装Apk** @param context* @param apkPath*/public static void installApk(Context context, String apkPath) {Intent intent = new Intent(Intent.ACTION_VIEW);intent.setDataAndType(Uri.parse("file://" + apkPath),"application/vnd.android.package-archive");context.startActivity(intent);}

Constants:


public class Constants {public static final String PATCH_FILE = "apk.patch";public static final String URL_PATCH_DOWNLOAD = "http://000.000.0.000:8080/" +PATCH_FILE;    //这里换成自己的服务器路径public static final String SD_CARD = Environment.getExternalStorageDirectory() + "/";//新版本apk的目录public static final String NEW_APK_PATH = SD_CARD + "dn_apk_new.apk";public static final String PATCH_FILE_PATH = SD_CARD + PATCH_FILE;
}

DownLoadUtils:


public class DownLoadUtils {/*** 下载差分包* @param url* @return* @throws Exception*/public static File download(String url){File file = null;InputStream is = null;FileOutputStream os = null;try {file = new File(Environment.getExternalStorageDirectory(),Constants.PATCH_FILE);if (file.exists()) {file.delete();}HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();conn.setDoInput(true);is = conn.getInputStream();os = new FileOutputStream(file);byte[] buffer = new byte[1*1024];int len = 0;while((len = is.read(buffer)) != -1){Log.d("Tim", String.valueOf(len));os.write(buffer, 0, len);}} catch(Exception e){e.printStackTrace();}finally{try {os.close();} catch (IOException e) {e.printStackTrace();}try {is.close();} catch (IOException e) {e.printStackTrace();}}return file;}
}


我们先copy这几个类。

copy C文件到cpp目录

把bspatch.c的main方法修改一下名字,因为一个应用程序只能有一个main方法,

在bspatch.c的最下面添加一个自己的jni方法,给自己的应用程序调用,把方法路径修改成自己的或者自己可以在BsPatch.java的native里自己生成

/** Class:     路径修改成自己的* Method:    patch* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I*/
JNIEXPORT jint JNICALL Java_com_112_BsPatch_patch (JNIEnv *env, jclass jazz, jstring oldPath_jstr, jstring newPath_jstr, jstring patchPath_jstr){LOGI("jni patch begin...");int ret = -1;char *oldPath = (*env) ->GetStringUTFChars(env , oldPath_jstr ,JNI_FALSE);char *newPath = (*env) ->GetStringUTFChars(env , newPath_jstr ,JNI_FALSE);char *patchPath = (*env) ->GetStringUTFChars(env , patchPath_jstr ,JNI_FALSE);int argc = 4;char *argv[4];argv[0] = "JasonDsPatch";argv[1] = oldPath;argv[2] = newPath;argv[3] = patchPath;//如果成功的话,ret等于0ret = bspatch_main(argc ,argv);(*env) ->ReleaseStringUTFChars(env , oldPath_jstr , oldPath);(*env) ->ReleaseStringUTFChars(env , newPath_jstr , newPath);(*env) ->ReleaseStringUTFChars(env , patchPath_jstr , patchPath);return ret;
}

在CmakeList里面添加所有的C文件

把自己的c++文件删掉,不删也行,不过CmakeList要自己添加一下

然后自己动手可以试一下,本人亲测可用!


博主偷个懒,直接发个demo吧,demo地址

Android NDK实现增量更新相关推荐

  1. Android APP增量更新

    最近项目推进app的增量更新方案,特意看了几篇文章,先来两个博客地址 http://my.oschina.net/liucundong/blog/160436 https://github.com/c ...

  2. Android 版本更新,支持增量更新

    AppSmartUpdate 项目地址:itlwy/AppSmartUpdate 简介: a smart lib for updating app / Android 版本更新,支持增量更新 更多:作 ...

  3. Android 如何实现增量更新

    什么是增量更新? 现在的APP安装包体积越来越大,几百兆甚至上G的,当APP更新时不再是消耗大量的流量下载一个完整安装包,而是消耗相对很少的流量下载一个增量包(差分包),采用谷歌Smart App U ...

  4. Android友盟增量更新

    1.增量升级的原理  增量更新的原理就是将本地apk与服务器端最新版本比对,并得到差异包.比如现在的版本是1.1.4,大小是7.2M,新版本是1.1.5.大小是7.3M.我们发现两个版本只有0.1M的 ...

  5. android APP自动增量更新

    APP自动增量更新 抽取的Android自动更新库,目的是几行代码引入更新功能,含服务端代码,欢迎Star,欢迎Fork,谢谢- 博客同步自:个人博客主页 代码github: https://gith ...

  6. Android应用内增量更新

    #Android 增量更新实现 原本来腾讯课堂中了解到了一些关于增量更新的知识,特地写一篇博客来记录下. 手机端实现 https://github.com/ItsFated/DiffPatch-app ...

  7. android 补丁包增量更新

    ●功能版本:增量更新是Google 4.1增加的新功能 ●功能背景: 现在的安卓Apk越来越大,而在此之前如果用户发现有新版本的话,需要重新把对应程序的新版本下载下来,有时候并不是重大更新,仅仅只是优 ...

  8. android+仿友盟更新,android友盟增量更新

    1.增量升级的原理 增量更新的原理就是将本地apk与服务器端最新版本比对,并得到差异包.比如现在的版本是1.1.4,大小是7.2M,新版本是1.1.5.大小是7.3M.我们发现两个版本只有0.1M的差 ...

  9. Android实现应用的增量更新\升级

    转载请注明出处:http://blog.csdn.net/yyh352091626/article/details/50579859 GitHub更新:https://github.com/smuyy ...

最新文章

  1. js页面跳转常用的几种方式
  2. AI、ML论文网站、如何阅读论文?
  3. 【LeetCode】LeetCode之打家劫舍Ⅱ——暴力递归+动态规划解决循环问题+DP空间优化
  4. log4jdbc mysql_[简单]log4jdbc-log4j2配置简记_MySQL
  5. WCF系列_分布式事务(下)
  6. 传世经典书丛-UNIX编程艺术
  7. SQL之正则表达式的简单使用
  8. 12.4 正项数项级数收敛的充要条件及比较判别法
  9. 跳舞毯 [HDU2154]
  10. mysql 1556_mysqldump: Got error: 1556: You can't use locks with log tables.
  11. 【安防监控】如何利用无人机技术严防夏天溺水?
  12. 程序员的福利--百度的71个开源项目
  13. 192.168.0.0/24是啥意思?
  14. 搭建系统App、小程序到底要多少钱?
  15. python关键词 打标签详解_Python学习日记13|利用python制作简书首页热门文章关键词标签云...
  16. 24、基于51单片机公交车语音播报加时间显示系统设计
  17. 理解 Array.prototype.slice.apply
  18. ajax绑值,AJAX请求,返回json进行页面绑值
  19. 《安富莱嵌入式周报》第244期:2021.12.13--2021.12.19
  20. Android auto 小米 mix,安卓之父做手机:这是史上最完美的“小米 MIX”

热门文章

  1. Nao 类人机器人,Aldebaran Robotics公司
  2. 黑马程序员—我和我男朋友在黑马的故事,感谢黑马~~~~~~~~...
  3. 智能手机上的显卡 解读ARM架构主流的GPU
  4. 小米万兆路由器里的Docker安装可道云(kodbox)私有网盘
  5. c语言编程离高考还有多少天,距离2020高考还有多少天 高考倒计时
  6. (毕业设计资料)基于单片机声光控智能路灯系统仿真设计
  7. 基于Android8 打开VoWifi 设置
  8. C/C++超详细的关键字大全!
  9. 微信小程序实时监测网络状态变化
  10. 装装糊涂,世事皆通达