实验:
MySejahtera app 在没网络下,扫描二维码后, 政府还能不能收到该 check-in?
实验结果:
每次点击 "close" 按钮后的十秒, 都会调用 js 的 checkAndSync() 函数, 检查 checkInQue 数据库表之前有没有失败的请求 queue,有的话就(等多一秒)一个个调用 syncCheckIn() 函数尝试 "/clockin" API 终点请求上传。"Clear storage" 会清除该 queue,"Clear Cache" 则不会。
实验总结:
请确保点击 "close" 按钮后的十一秒后有网络,才能上传之前没网络的 check-in 给政府。即使你扫描新的二维码, 是不会包括之前没网络所累积的 check-in, 必须点击 "close" 按钮等十一秒。十一秒是开始上传的时间,上传全部需时十一秒以上。
我也花了很长时间在 smali 在 enable remote debugging 函数附近加 Log.d()。
实验目标反而是次要,主要目标是顺便学习 smali, 否则要直接在 smali 加 (或删 if/else) enable remote debugging 有何难度?
加 Log.d 原本并不难,可是 `smali/org/apache/cordova/engine/SystemWebViewEngine.smali` 的 `initWebViewSettings()` 恰好是 `.locals 15`。
纯粹改成 16 而不去考虑改其它东西是不大行的,常遇到 error 却不理解为什么不 work。
着手找了 .locals 15 的 java 代码再加大量的代码,终于了解原理和 .locals 的规则。
我之前读的是这个教程,这个教程没提 .locals 15 和 { vx .. vy} 的情况:
首先, .registers 是真的跟 .locals 一样,比 .locals 纯粹多了函数 params 数目, 所以不需要奢望 .registers 可以做到 .locals 做不到的东西。
然后,v17 (.locals v16 + this p0) 意思是可以使用新的 v16, v16 可以想象为 temporary/virtual-variable(我这么形容的), 不实际存在, 但是想象它存在 非-registers 的地方。
要用 v16? 大于 v15 不能直接使用,但有两种使用方式:
【方法一】 先 move-object/from16 v4, v16 复制去小于 v16 的 v4,然后才用 v4。
【方法二】用 { v7 .. v16} ,能写 v16,前提是那些 registers 必须 v7, v8, v9 .. v16 准备好数值。
这样就完了?很可惜,我开头也以为这么容易, 可是其实要考虑 p。
你改成 .locals 16 后,之前的 p0 怎么办?
本来 p1 -> p0 占用 .locals vMax 倒数的目的就是为了方便加 vN 不会影响到现成的 pN, 可以轻松加 smali,对不?
很可惜,.locals 15 加成 16, smali 这特殊情况下帮不到你,需要手动改代码。
假设只有 this p0, p0 之前是 v15,然后你改成 .locals 16,那么你现在用 v15 是没问题的,p0 就升级成 v16。
So far so good, 很可惜,上面说了,大于 v15 的 registers 都是 temporary/virtual registers, 使用的方法不同。
因此你必须改所有涉及 p0 的代码, 先 move-object 才使用抑或更多工的 { pX .. pY}。
我上面强调 .locals 15 加成 16 是 “特殊情况”,是真的很 “特殊”, 即使你 .locals 21 加成 22 是不会有问题的,因为 .locals 21 + 1 existing 的 p0 并没有更改 “使用方法”(已经是 move/{..}了)。 只有 v15 去 v16 才导致 existing 的 p0 从普通方法 “突变” 成 move/{..} 的方法。
这个问题不出所料,网上也常提起。
这还没完,v15 还没考虑 params 的数目。譬如 .locals 12 + params 6, 纯粹改成 .locals 13 也是有问题的。因此还要考虑之前 params 有没有属于 v15 的。可以 15 - .locals 12 = p3 要改。如果 .locals 加 2, 那么 p3 和 p2 得连续改。
如果是小数目的 p0 还好,可是 MySejahtera 的 `initWebViewSettings()` 用了大量的 p0,谁这么得空改完?不是不可能,而是很花时间而已。
最后我检查到 v13 少用到(要不然就是用了不再需要, 可以 override)。所以比较快的方式是只 assign v13, 然后重复用在 Log.d 即可达到我的加 Log.d 小目标。
首先, .registers 是真的跟 .locals 一样,比 .locals 纯粹多了函数 params 数目, 所以不需要奢望 .registers 可以做到 .locals 做不到的东西。
然后,v17 (.locals v16 + this p0) 意思是可以使用新的 v16, v16 可以想象为 temporary/virtual-variable(我这么形容的), 不实际存在, 但是想象它存在 非-registers 的地方。
要用 v16? 大于 v15 不能直接使用,但有两种使用方式:
【方法一】 先 move-object/from16 v4, v16 复制去小于 v16 的 v4,然后才用 v4。
【方法二】用 { v7 .. v16} ,能写 v16,前提是那些 registers 必须 v7, v8, v9 .. v16 准备好数值。
这样就完了?很可惜,我开头也以为这么容易, 可是其实要考虑 p。
你改成 .locals 16 后,之前的 p0 怎么办?
本来 p1 -> p0 占用 .locals vMax 倒数的目的就是为了方便加 vN 不会影响到现成的 pN, 可以轻松加 smali,对不?
很可惜,.locals 15 加成 16, smali 这特殊情况下帮不到你,需要手动改代码。
假设只有 this p0, p0 之前是 v15,然后你改成 .locals 16,那么你现在用 v15 是没问题的,p0 就升级成 v16。
So far so good, 很可惜,上面说了,大于 v15 的 registers 都是 temporary/virtual registers, 使用的方法不同。
因此你必须改所有涉及 p0 的代码, 先 move-object 才使用抑或更多工的 { pX .. pY}。
我上面强调 .locals 15 加成 16 是 “特殊情况”,是真的很 “特殊”, 即使你 .locals 21 加成 22 是不会有问题的,因为 .locals 21 + 1 existing 的 p0 并没有更改 “使用方法”(已经是 move/{..}了)。 只有 v15 去 v16 才导致 existing 的 p0 从普通方法 “突变” 成 move/{..} 的方法。
这个问题不出所料,网上也常提起。
这还没完,v15 还没考虑 params 的数目。譬如 .locals 12 + params 6, 纯粹改成 .locals 13 也是有问题的。因此还要考虑之前 params 有没有属于 v15 的。可以 15 - .locals 12 = p3 要改。如果 .locals 加 2, 那么 p3 和 p2 得连续改。
如果是小数目的 p0 还好,可是 MySejahtera 的 `initWebViewSettings()` 用了大量的 p0,谁这么得空改完?不是不可能,而是很花时间而已。
最后我检查到 v13 少用到(要不然就是用了不再需要, 可以 override)。所以比较快的方式是只 assign v13, 然后重复用在 Log.d 即可达到我的加 Log.d 小目标。
然后 `<application android:debuggable="true"` 也很好用,改了后,不需要 root 也能通过
`adb exec-out run-as my.gov.onegovappstore.mysejahtera cat /data/user/0/my.gov.onegovappstore.mysejaht
era/databases/__ionicstorage > __ionicstorage`
的方式从手机复制数据库到电脑 (现在的 Android 的 run-as 不能直接 cp /sdcard/, 所以才比较折腾)。
其实 `android:debuggable="true"` 也能影响上面 `initWebViewSettings()` 的 `if ApplicationInfo flags == true` 而 enable remote debugging。
No comments:
Post a Comment