}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public void registerActivityLifecycleCallback(Application.ActivityLifecycleCallbacks callbacks) {
getApplication().registerActivityLifecycleCallbacks(callbacks);
}
@Override
public void onTerminate() {
super.onTerminate();
Beta.unInit();
}
}
注意:
SampleApplicationLike这个类是Application的代理类,以前所有在Application的实现必须要全部拷贝到这里,在onCreate方法调用SDK的初始化方法,在onBaseContextAttached中调用Beta.installTinker(this)。
最后在清单文件中,声明改造好的Application(注意不是ApplicationLike):
android:name=“com.lqr.SampleApplication” …> 3、配置Bugly 这是Bugly官方给出的配置,应有尽有,注释也很nice,请仔细看看,对项目的功能拓展与用户体验有帮助: private void configTinker() { // 设置是否开启热更新能力,默认为true Beta.enableHotfix = true; // 设置是否自动下载补丁,默认为true Beta.canAutoDownloadPatch = true; // 设置是否自动合成补丁,默认为true Beta.canAutoPatch = true; // 设置是否提示用户重启,默认为false Beta.canNotifyUserRestart = true; // 补丁回调接口 Beta.betaPatchListener = new BetaPatchListener() { @Override public void onPatchReceived(String patchFile) { Toast.makeText(mContext, “补丁下载地址” + patchFile, Toast.LENGTH_SHORT).show(); } @Override public void onDownloadReceived(long savedLength, long totalLength) { Toast.makeText(mContext, String.format(Locale.getDefault(), “%s %d%%”, Beta.strNotificationDownloading, (int) (totalLength == 0 ? 0 : savedLength * 100 / totalLength)), Toast.LENGTH_SHORT).show(); } @Override public void onDownloadSuccess(String msg) { Toast.makeText(mContext, “补丁下载成功”, Toast.LENGTH_SHORT).show(); } @Override public void onDownloadFailure(String msg) { Toast.makeText(mContext, “补丁下载失败”, Toast.LENGTH_SHORT).show(); } @Override public void onApplySuccess(String msg) { Toast.makeText(mContext, “补丁应用成功”, Toast.LENGTH_SHORT).show(); } @Override public void onApplyFailure(String msg) { Toast.makeText(mContext, “补丁应用失败”, Toast.LENGTH_SHORT).show(); } @Override public void onPatchRollback() { } }; // 设置开发设备,默认为false,上传补丁如果下发范围指定为“开发设备”,需要调用此接口来标识开发设备 Bugly.setIsDevelopmentDevice(mContext, false); // 多渠道需求塞入 // String channel = WalleChannelReader.getChannel(getApplication()); // Bugly.setAppChannel(getApplication(), channel); // 这里实现SDK初始化,appId替换成你的在Bugly平台申请的appId Bugly.init(mContext, “e9d0b7f57f”, true); } 这里就用到了一开始获取到的App ID了,将其传入Bugly.init()方法的第二个参数,切记,用你自己的App ID。 其中如下两个方法很重要: 设置当前设备是不是开发设备,这跟Bugly上传补丁包时所选的"下发范围"有关。 这个方法除了设置App ID外,还可以设置是否输出Log,可以观察到Bugly在App启动时做了哪些联网操作。 六、AndroidManifest.xml ===================== 1、 权限配置 2、Activity配置 android:name=“com.tencent.bugly.beta.ui.BetaActivity” android:configChanges=“keyboardHidden|orientation|screenSize|locale” android:theme="@android:style/Theme.Translucent"/> 3、FileProvider配置 android:name=“android.support.v4.content.FileProvider” android:authorities="${applicationId}.fileProvider" android:exported=“false” android:grantUriPermissions=“true”> android:name=“android.support.FILE_PROVIDER_PATHS” android:resource="@xml/provider_paths"/> 如果你使用的第三方库也配置了同样的FileProvider, 可以通过继承FileProvider类来解决合并冲突的问题,示例如下: android:name=".utils.BuglyFileProvider" android:authorities="${applicationId}.fileProvider" android:exported=“false” android:grantUriPermissions=“true” tools:replace=“name,authorities,exported,grantUriPermissions”> android:name=“android.support.FILE_PROVIDER_PATHS” android:resource="@xml/provider_paths" tools:replace=“name,resource”/> 4、升级SDK下载路径配置 在res目录新建xml文件夹,创建provider_paths.xml文件如下: 注:1.3.1及以上版本,可以不用进行以上配置,aar已经在AndroidManifest配置了,并且包含了对应的资源文件。 七、混淆 ==== -dontwarn com.tencent.bugly.** -keep public class com.tencent.bugly.**{*;} -keep class android.support.**{*;} 好了,集成完毕,接下来就是制作基准包、补丁包和上传补丁包了。 八、制作基准包 ======= 在app编码完成并测试完成后,就是打包上线了,上线前打的包就是基准包啦,下面我们就来制作基准包,分3步: 打开app下的tinker-support.gradle文件。 将带"base"的tinkerId注释解开,并注释掉带"patch"的tinkerId。 双击运行build下的assembleRelease。 通常主Module的名字是"app",但我这个Demo是"tinker-bugly",所以你执行第3步时,要根据具体项目找到要制作基准包的主Module。 AS在执行assembleRelease指令时,就是在编译基准包了,当编译完成时,app的build目录下会自动生成基准包文件夹,以时间戳来命名的(也就是说,每次执行assembleRelease指令都会在build目录创建不同的基准包文件夹)。 这3个文件对之后制作补丁包来说是相当重要的,你需要做的就是将这3个文件保存好,可以保存到云盘、Git服务器上等等,但就不要让它就这么放着,因为在你执行clean Project时,app的build目录会被删除,这样基准包及mapping与R文件都会丢失。 到这里,你就可以把它(基准包:tinker-bugly-release.apk)上架到应用市场了。试下Demo: tip:加固与多渠道打包 本篇不涉及具体的加固与多渠道打包。 如果你的app需要加固,那就需要在制作基准包之前,将tinker-support.gradle文件的isProtectedApp = true的注释去掉,然后加固,重新签名,最后上架,它对加固平台也有一定的要求。 详情见「Bugly热更新使用范例文档最后:加固打包」部分。 分「gradle配置productFlavors方式」与「多渠道打包工具打多渠道包方式(推荐)」。 详情见「Bugly热更新使用范例文档:多渠道打包」部分。 九、补丁包 ===== 现在要动态修复App了,对于代码修复、so库修复、资源文件修复,分别对应Demo中的"say something"、“get string from .so”、“我的头像”,修复过程无非是改代码,替换so文件,替换资源文件,这里就不演示了,直接开始制作补丁包,先将tinker-support.gradle文件打开。 1、基准包命名 确保基准包及相关文件的命名与配置文件中的一致: 2、修改baseApkDir与tinkerId 修改baseApkDir的值为基准包所有文件夹的名字。 注释掉带"base"的tinkerId,取消带"patch"的tinkerId的注释(多次生成补丁时,记得修改"计数",区分不同的补丁)。 3、执行编译,生成补丁 打开侧边的Gradle标签,找到项目的主Module,双击tinker-support下的buildTinkerPatchRelease指令,生成补丁包。 当编译完成后,在app的build/outputs/patch目录下会在"patch_singed_7zip.apk"文件,它就是补丁包,双击打开它,可以看到其中有一个YAPATCH.MF,里面记录了基准包与补丁包的tinkerId(两者是肯定不同,如果一样则说明配置有问题了)。 十、上传补丁包 ======= 1、流程图解 首先,点击进入「Bugly产品页面」,或点击“我的产品 ”查看我的产品。 点击你要管理的产品后,依次点击"应用升级"、“热更新”,可以查看到该产品的补丁下发情况(这个产品我还没上传过补丁,故一片空白)。 按下图顺序操作即可上传补丁包: 2、上传失败分析 有可能你在上传完补丁包时,页面会提示"未匹配到可应用补丁包的App版本,请确认补丁包的基线版本是否已经发布"。 遇到这种情况请先冷静,首先来说明一件事:Bugly怎么知道基线版本是否已经发布? 通常按我们理解的,基准包发布就是上架到应用市场,但应用市场又不会通知Bugly某某产品已经上架了,对吧。其实,Bugly的上架通知是这样的:当基准包在手机上启动时,Bugly框架就会让App联网通知Bugly的服务器,同时上传当前App的版本号、tinkerId等信息,它这么做的目的有如下两个: 标记某个tinkerId的基准包已经被安装到手机上使用了(即发布)。 获取该tinkerId的基准包最新的补丁信息。 所以,当出现了"未匹配到可应用补丁包的App版本,请确认补丁包的基线版本是否已经发布"这样的提示时,可以确定,这个基准包的tinkerId等信息没有被上传到Bugly服务器,对此,鄙人将踩过的坑总结起来,摸索出了自己的解决方法,分如下几步: 检查App是否能够联网。 检查App ID是否正确。 结合enableProxyApplication的取值,检查AndroidManifest.xml中声明的Application是否写对。 检查Bugly的安装是不是在attachBaseContext()或onBaseContextAttached()方法中完成。 像我就犯过这样的错,明明在tinker-support.gradle文件中设置了enableProxyApplication = true,结果在AndroidManifest.xml中却声明了TinkerApplication的继承类。 所以这里只需要将AndroidManifest.xml中声明我们自定义的Application即可(MyApplication)。 除了联网问题以外,其他的几种情况都需要重新生成基准包。这里再分享一个可以快速确定App是否有上传过版本信息的方法: 3、上传成功 先验证下上面的方法,当我把问题解决掉之后,把重新生成的基准包安装到手机上打开(此时Bugly框架会上传App的版本号、tinkerId到服务器),再查看"版本管理",出现了,版本号为"1.0"(其实就是App的versionName)。 再回头来看看上传补丁,这次又会有什么不同呢? 耶,成功。点击"立即下发",可以看到现在补丁处于"下发中"状态: 随便来看看用户手中的App是什么反应吧(真正将补丁下发到用户手机上的这段时间可能会有点久,不是立即下发的): 再回头看看Bugly服务器上的补丁下发情况: 十一、其他 ===== 1、补丁管理 Bugly服务器除了可以上传下发补丁外,还可以对补丁进行管理: 停止下发:不再把该补丁下发到客户手机上(停止后可重新开启)。 撤回:将Bugly服务器上的某个补丁删掉,这个操作是不可逆的(不知道用户手机上被成功打上的补丁是否也会被卸载)。 编辑:可以修改"下发范围"(开发设备、全量设备、备注等等)。 历史:查看修改记录。 2、强调一下一些需要注意的地方 一个基准包可以有多个补丁包,Bugly会将最新的补丁进行下发(旧补丁默认会变成"停止下发状态"),客户手机上的App的旧补丁会被新补丁覆盖。 制作基础包时,请使用带"base"的tinkerId,执行的是assembleRelease指令。 制作基础包后,一定要将baseApk、mapping.txt、R.txt保存好,不能弄丢了。 制作补丁包时,先将baseApkDir的值修改为基准包所有文件夹的名字,然后启用带"patch"的tinkerId,同时修改"计数",执行的是buildTinkerPatchRelease指令。 制作补丁包后,最后打开它检查YAPATCH.MF文件中的from和to信息,检查该补丁包对应的基准包的tinkerId是否正确。 建议上线的基准包将Bugly的Log输出关闭:Bugly.init(mContext, AppID, false); 如果是测试补丁包是否用效果,建议设置为开发设备:Bugly.setIsDevelopmentDevice(mContext, true); so文件需要手动先调用一下 TinkerLoadLibrary.installNavitveLibraryABI(this, CPU_ABI) 方法才能生效。 3、Bugly官方文档 Bugly Android热更新使用指南 Bugly Android热更新详解 说一千道一万,不如自己去行动。要想在移动互联网的下半场是自己占有一席之地,那就得从现在开始,从今天开始,马上严格要求自己,既重视业务实现能力,也重视基础和原理。基础夯实好了,高楼才能够平地而起,稳如泰山。 最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2020-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。 还有 高级架构技术进阶脑图、Android开发面试专题资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。 点击: 《Android架构视频+BAT面试专题PDF+学习笔记》 即可免费获取~ oid热更新详解]( ) 说一千道一万,不如自己去行动。要想在移动互联网的下半场是自己占有一席之地,那就得从现在开始,从今天开始,马上严格要求自己,既重视业务实现能力,也重视基础和原理。基础夯实好了,高楼才能够平地而起,稳如泰山。 最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的24套腾讯、字节跳动、阿里、百度2020-2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。 还有 高级架构技术进阶脑图、Android开发面试专题资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。 [外链图片转存中…(img-Uh7TZwam-1646385426900)] [外链图片转存中…(img-cLuo57Ii-1646385426900)] [外链图片转存中…(img-Kc5HNjsz-1646385426901)] 点击: 《Android架构视频+BAT面试专题PDF+学习笔记》 即可免费获取~ 网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
Bugly混淆规则
避免影响升级功能,需要keep住support包的类
1、加固
2、多渠道打包
最后
最后