架构日记(八)Android热修复框架的集成

APP 0 1437
00224176
00224176 版主 - APP 关注 2021年7月22日 16:16 编辑
<p style="outline: 0px; --tw-shadow:0 0 #0000 ; --tw-ring-inset:var(--tw-empty, ); --tw-ring-offset-width:0px; --tw-ring-offset-color:#fff; --tw-ring-color:rgba(66, 153, 225, 0.5); --tw-ring-offset-shadow:0 0 #0000; --tw-ring-shadow:0 0 #0000 ; margin-top: 0px; margin-bottom: 16px; font-size: 16px; color: rgb(77, 77, 77); overflow: auto hidden; overflow-wrap: break-word; font-family: -apple-system, &quot;SF UI Text&quot;, Arial, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, sans-serif, SimHei, SimSun; line-height: 26px !important;">至于AndFix和SoPhix的原理,机制我就不赘言了,网上大把的资料,阿里云上也有非常详细的说明。本文注意介绍集成的步骤</p><p style="outline: 0px; --tw-shadow:0 0 #0000 ; --tw-ring-inset:var(--tw-empty, ); --tw-ring-offset-width:0px; --tw-ring-offset-color:#fff; --tw-ring-color:rgba(66, 153, 225, 0.5); --tw-ring-offset-shadow:0 0 #0000; --tw-ring-shadow:0 0 #0000 ; margin-top: 0px; margin-bottom: 16px; font-size: 16px; color: rgb(77, 77, 77); overflow: auto hidden; overflow-wrap: break-word; font-family: -apple-system, &quot;SF UI Text&quot;, Arial, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, sans-serif, SimHei, SimSun; line-height: 26px !important;">一· AndFix集成</p><p style="outline: 0px; --tw-shadow:0 0 #0000 ; --tw-ring-inset:var(--tw-empty, ); --tw-ring-offset-width:0px; --tw-ring-offset-color:#fff; --tw-ring-color:rgba(66, 153, 225, 0.5); --tw-ring-offset-shadow:0 0 #0000; --tw-ring-shadow:0 0 #0000 ; margin-top: 0px; margin-bottom: 16px; font-size: 16px; color: rgb(77, 77, 77); overflow: auto hidden; overflow-wrap: break-word; font-family: -apple-system, &quot;SF UI Text&quot;, Arial, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, sans-serif, SimHei, SimSun; line-height: 26px !important;">config.gradle</p><pre><code>dependencies = [<br> ...<br> andfix : "com.alipay.euler:andfix:0.5.0@aar"<br> <br> ]</code></pre><p><span style="color: rgb(77, 77, 77); font-family: -apple-system, &quot;SF UI Text&quot;, Arial, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, sans-serif, SimHei, SimSun; font-size: 16px;">base.gradle</span><br></p><pre><code>api rootProject.ext.dependencies["andfix"]</code></pre><p><span style="color: rgb(77, 77, 77); font-family: -apple-system, &quot;SF UI Text&quot;, Arial, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, sans-serif, SimHei, SimSun; font-size: 16px;">MyApplication</span><br></p><pre><code>public class MyApplication extends BaseApplication {<br> <br> private RefWatcher refWatcher;<br> private PatchManager mPatchManager;<br> <br> <br> @Override<br> public void onCreate() {<br> super.onCreate();<br> refWatcher= setupLeakCanary();<br> mPatchManager = new PatchManager(this);<br> mPatchManager.init("1.0");<br> Log.d("TAG","inited");<br> <br> mPatchManager.loadPatch();<br> }<br> <br> private RefWatcher setupLeakCanary() {<br> if (LeakCanary.isInAnalyzerProcess(this)) {<br> return RefWatcher.DISABLED;<br> }<br> return LeakCanary.install(this);<br> }<br> <br> public static RefWatcher getRefWatcher(Context context) {<br> MyApplication leakApplication = (MyApplication) context.getApplicationContext();<br> return leakApplication.refWatcher;<br> }<br>}</code></pre><p style="outline: 0px; --tw-shadow:0 0 #0000 ; --tw-ring-inset:var(--tw-empty, ); --tw-ring-offset-width:0px; --tw-ring-offset-color:#fff; --tw-ring-color:rgba(66, 153, 225, 0.5); --tw-ring-offset-shadow:0 0 #0000; --tw-ring-shadow:0 0 #0000 ; margin-top: 0px; margin-bottom: 16px; font-size: 16px; color: rgb(77, 77, 77); overflow: auto hidden; overflow-wrap: break-word; font-family: -apple-system, &quot;SF UI Text&quot;, Arial, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, sans-serif, SimHei, SimSun; line-height: 26px !important;">&nbsp;MainActivity的点击事件中一个弹出Toast的函数作为测试热修复的测试函数</p><p style="outline: 0px; --tw-shadow:0 0 #0000 ; --tw-ring-inset:var(--tw-empty, ); --tw-ring-offset-width:0px; --tw-ring-offset-color:#fff; --tw-ring-color:rgba(66, 153, 225, 0.5); --tw-ring-offset-shadow:0 0 #0000; --tw-ring-shadow:0 0 #0000 ; margin-top: 0px; margin-bottom: 16px; font-size: 16px; color: rgb(77, 77, 77); overflow: auto hidden; overflow-wrap: break-word; font-family: -apple-system, &quot;SF UI Text&quot;, Arial, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, sans-serif, SimHei, SimSun; line-height: 26px !important;">分别是</p><pre><code>private void showMsg(){<br> Toast.makeText(this,"new",Toast.LENGTH_LONG).show();<br>}</code></pre><pre><code>private void showMsg(){<br> Toast.makeText(this,"old",Toast.LENGTH_LONG).show();<br>}</code></pre><p style="outline: 0px; --tw-shadow:0 0 #0000 ; --tw-ring-inset:var(--tw-empty, ); --tw-ring-offset-width:0px; --tw-ring-offset-color:#fff; --tw-ring-color:rgba(66, 153, 225, 0.5); --tw-ring-offset-shadow:0 0 #0000; --tw-ring-shadow:0 0 #0000 ; margin-top: 0px; margin-bottom: 16px; font-size: 16px; color: rgb(77, 77, 77); overflow: auto hidden; overflow-wrap: break-word; font-family: -apple-system, &quot;SF UI Text&quot;, Arial, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, sans-serif, SimHei, SimSun; line-height: 26px !important;">接下来就是生成jks签名文件(AndroidStudio)</p><p style="outline: 0px; --tw-shadow:0 0 #0000 ; --tw-ring-inset:var(--tw-empty, ); --tw-ring-offset-width:0px; --tw-ring-offset-color:#fff; --tw-ring-color:rgba(66, 153, 225, 0.5); --tw-ring-offset-shadow:0 0 #0000; --tw-ring-shadow:0 0 #0000 ; margin-top: 0px; margin-bottom: 16px; font-size: 16px; color: rgb(77, 77, 77); overflow: auto hidden; overflow-wrap: break-word; font-family: -apple-system, &quot;SF UI Text&quot;, Arial, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, sans-serif, SimHei, SimSun; line-height: 26px !important;">分别打出新老两个签名包</p><p style="outline: 0px; --tw-shadow:0 0 #0000 ; --tw-ring-inset:var(--tw-empty, ); --tw-ring-offset-width:0px; --tw-ring-offset-color:#fff; --tw-ring-color:rgba(66, 153, 225, 0.5); --tw-ring-offset-shadow:0 0 #0000; --tw-ring-shadow:0 0 #0000 ; margin-top: 0px; margin-bottom: 16px; font-size: 16px; color: rgb(77, 77, 77); overflow: auto hidden; overflow-wrap: break-word; font-family: -apple-system, &quot;SF UI Text&quot;, Arial, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, sans-serif, SimHei, SimSun; line-height: 26px !important;">放在同一个文件夹下面,如图所示</p><p style="outline: 0px; --tw-shadow:0 0 #0000 ; --tw-ring-inset:var(--tw-empty, ); --tw-ring-offset-width:0px; --tw-ring-offset-color:#fff; --tw-ring-color:rgba(66, 153, 225, 0.5); --tw-ring-offset-shadow:0 0 #0000; --tw-ring-shadow:0 0 #0000 ; margin-top: 0px; margin-bottom: 16px; font-size: 16px; color: rgb(77, 77, 77); overflow: auto hidden; overflow-wrap: break-word; font-family: -apple-system, &quot;SF UI Text&quot;, Arial, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, sans-serif, SimHei, SimSun; line-height: 26px !important;"><img src="https://51techud.yykj.com:9002/forumpic/20210722161431_vx.png" style="max-width:100%;"><br></p><p>接下来要做的就是下载apkpatch-1.0.3.jar工具包,内不包含了shell和bat脚本<br><br>本文是MAC下,采用shell脚本<br><br>执行生成补丁包命令:<br><br>./apkpatch.sh -f new.apk -t old.apk -k mytest.jks -p 12205226 -a key0 -e 12205226 -o patch<br>注意:由于命令行中写了new.apk &amp;&amp; old.apk,所以请务必将打包出来的包名修改名称,与此同名<br><br>大家对比签名文件就知道哪些是参数了</p><pre><code>signingConfigs{<br> config {<br> keyAlias 'key0'<br> keyPassword '12205226'<br> storeFile file('/Users/mac/Desktop/mytest.jks')<br> storePassword '12205226'<br> }<br>}</code></pre><p><span style="color: rgb(77, 77, 77); font-family: -apple-system, &quot;SF UI Text&quot;, Arial, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, sans-serif, SimHei, SimSun; font-size: 16px;">提供一些apkapatch命令的说明:</span><br></p><pre><code>usage: apkpatch -f &lt;new&gt; -t &lt;old&gt; -o &lt;output&gt; -k &lt;keystore&gt; -p &lt;***&gt; -a &lt;alias&gt; -e &lt;***&gt;<br> -a,--alias &lt;alias&gt; keystore entry alias.<br> -e,--epassword &lt;***&gt; keystore entry password.<br> -f,--from &lt;loc&gt; new Apk file path.<br> -k,--keystore &lt;loc&gt; keystore path.<br> -n,--name &lt;name&gt; patch name.<br> -o,--out &lt;dir&gt; output dir.<br> -p,--kpassword &lt;***&gt; keystore password.<br> -t,--to &lt;loc&gt; old Apk file path.</code></pre><p><span style="color: rgb(77, 77, 77); font-family: -apple-system, &quot;SF UI Text&quot;, Arial, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, sans-serif, SimHei, SimSun; font-size: 16px;">命令执行完后会在patch文件生成</span><br></p><p><img src="https://51techud.yykj.com:9002/forumpic/20210722161523_kp.png" style="max-width:100%;"><span style="color: rgb(77, 77, 77); font-family: -apple-system, &quot;SF UI Text&quot;, Arial, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, sans-serif, SimHei, SimSun; font-size: 16px;"><br></span></p><p>如果大家感兴趣呢可以去研究一下android反编译的三个套装 dex2jar工具可以将diff.dex专为 diff.dex.jar可以查看内部源码,会有标签标识出需要修复的函数名称。<br><br>主要是看.apatch文件,这个就是补丁包文件 根据代码中加载的名称可以修改.apatch的名称<br><br>mv new-86.......0.apatch yourname.apatch <br><br> 记下来安装old.apk<br><br>adb install old.apk<br><br>然后push 补丁文件到sd卡上,当然了,也可以通过服务器下载补丁文件<br><br>adb push ./out.apatch /sdcard<br><br>我的代码中的补丁文件名称定义为out.apatch 名称自行修改<br><br>接下来看调用的代码其实也非常简单</p><pre><code>private void loadPatch(){<br> String patchFileString = Environment.getExternalStorageDirectory()<br> .getAbsolutePath() + APATCH_PATH;<br> if(new File(patchFileString).exists()){<br> try {<br> MyApplication.mPatchManager.addPatch(patchFileString);<br> } catch (IOException e) {<br> e.printStackTrace();<br> }<br> Log.d("TAG",patchFileString);<br> }<br>// File f = new File(this.getFilesDir(), DIR + APATCH_PATH);<br>// if (f.exists()) {<br>// boolean result = new File(patchFileString).delete();<br>// if (!result) {<br>// Log.e("TAG", patchFileString + " delete fail");<br>// }<br>// }<br> }</code></pre><p>PATCH_PATH 的值是 “./out.apatch”<br><br>操作步骤 先安装old.apk点击事件show出来的是old 当我们push之后,执行loadPatch方法后,在点击就可以发现弹出的是new了<br><br>AndFix的原理上还是有缺陷的,涉及到虚拟机,而虚拟机以Android5.0为分界线有存在差异,特别是后面的厂家都有订制所以对于适配问题是一个非常挑战和头疼的事情,是不是有的小伙伴发现放到sdcard上死活不行,这就是不同的手机文件系统差异性造成的,建议使用网络下载apatch文件在addPatch()。<br><br>对于AndFix的兼容性问题。阿里给出了加强版的方案SoPhxi-HotFix方案。下一篇继续~<br><br>apatch工具下载地址 https://download.csdn.net/download/qq_20369621/12488056</p>
赞(0) 收藏(0)  分享
相关标签:
0个回复
  • 消灭零回复
Vaptcha启动中...