天天看點

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

熱更新系列目錄

  1. 熱更新你都知道哪些?
  2. 熱更新Sophix的爬坑之路
  3. 騰訊熱更新Tinker的故事
  4. 阿裡熱更新Sophix的故事

Sophix的爬坑之旅

  • 前言
  • 坑一:AndroidX 不相容
    • 開發環境
    • 爬坑過程
    • 小結
  • 坑二:patch 更新檔反複失效
    • 開發環境
    • 爬坑過程
  • 坑三:abandon initialization: callRealAppAttach
    • 小結
  • 補充知識
    • 1. enforce
    • 2. Root
  • 總結

部落格建立時間:2020.05.22

部落格更新時間:2021.02.23

前言

該篇部落格就是為了總結使用Sophix的過程中碰到的一些Bug及爬坑過程,希望各位極客還沒碰到,看了我的回顧總結後能對可能出現的困惑有幫助。

爬坑之旅記錄着我和Sophix技術支援團隊的交流和探讨Bug過程。每個軟體産品都會有Bug和待優化的地方,大膽懷疑和相信自己

Sophix與EMAS中的其他産品不一樣,需要單獨的進行穩健接入,使用EMAS的統一接入無效。

坑一:AndroidX 不相容

開發環境

win10 + android studio 3.5.1 + gradle-5.4.1 + 裝置API 5.1.1 + jdk1.8+ alicloud-android-hotfix:3.2.10

爬坑過程

這個Bug簡單來說就是Sophix 3.2.10的使用的時候

  • 不支援androidx,不支援生成patch初始化檢查。
  • 更新檔在加載成功重新開機後,會出現資源查找不到的問題

Android5.1.1在進行resource 資源更新是就會報如圖錯誤。

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

使用的Sophix熱更新工具使用的是3.2.4版,此時是不支援Androidx的檢查初始化。

​​

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

在2019.11,釘釘支援群說我是第一個使用Androidx進行熱更新的,估計當時阿裡對Sophix還未做大量的Androidx相容測試。最終的解決方法是通過我的堅持,Sophix最終進行修改優化相容Androidx。版本更新為3.2.12後支援了Androidx。心酸過程讓我一一道來。

我這個人有更新狂魔症,經常喜歡更新依賴,Gradle、插件等,反正隻要能更新的,能更新的我都要立馬更新,更新,是以踩了不少的坑,碰到了不少的雷。本着我不入地獄誰入地獄的精神,依然一往無前,樂此不疲。 不扯遠了,回正題。

首先,我發現将項目轉為Androidx後,發現自己的Sophix不能正常工作了,app打完更新檔就崩潰,于是各種測試,測試其他還未轉androidx的項目正常。沒辦法隻能求助全能的技術支援。

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

此時自己開始懷疑Sophix自身有問題,雖然Sophix是阿裡的技術團隊開發的,我也對它迷之自信,但是我的懷疑心戰勝了崇拜心,大膽的猜測。 雖然技術支援堅稱SDK不會有問題,但是我一直堅持自己的觀點。

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結
熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

通過不斷地多種測試,拿出我的多Gradle版本,多Android SDk版本的熱更新測試,終于說服了Sophix 進行Androidx的相容檢查,最終發現

sophix 3.2.8之前的sdk确實不相容android 5.0、5.1、 6.0的androidx apk進行熱更新.

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結
熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

問題解決

OK,經過Sophix的工程師修複,Sophix 3.2.10更新到Sophix 3.2.12就能解決5.0,5.1,6.0 中安裝了 Androidx的apk後,進行resource修複報錯崩潰的bug。

小結

  1. 常常看到阿裡騰訊等大廠的産品我們就會覺得他們的産品肯定厲害,肯定沒問題,其實這是個誤解。 作為程式員大家其實是認同軟體産品不能不存在Bug,好的和壞的就看bug率的多少了。 軟體産品是一個逐漸完善逐漸修複bug完善的過程。
  2. 對于任何開發中碰到的問題,我們要大膽的假設和猜測,不能根據自己的經驗去認為不可能。

    一切皆有可能,何況我們大多數人還不是特級大神,我們需要懷疑需要假設,通過實際的排查和驗證,才能排除不是那些因素造成了我們的問題。

    實踐是檢驗一切真理的唯一标準

坑二:patch 更新檔反複失效

這次碰到的Bug是更新檔反複失效,具體症狀是:更新檔成功後,下次重新開機軟體又恢複了原樣,繼續重新開機更新檔成功,繼續重新開機恢複原樣。簡直就是子子孫孫無窮盡也!

開發環境

  1. win10+gradle-5.6.4+android studio 3.6.3 + 裝置API 5.1.1+jdk1.8
  2. ‘com.aliyun.ams:alicloud-android-hotfix:3.2.14’
  3. 有個特殊的情況是,我的軟體需要進行系統簽名,制作成系統軟體以便于軟體的靜默安裝。生成的apk需要經如下檔案簽名,讓程式獲得系統級權限。
    熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結
    系統簽名還需在AndroidManifest.xml中配置

    android:sharedUserId="android.uid.system"

爬坑過程

首先進行相關因素排查,然後根據自己的進行假設,一步步驗證排除假設直至找到最終真相。

1. 緩存清理

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

首先懷疑我進行了清緩存操作,于是我把各種自動清理垃圾緩存的代碼操作屏蔽 和管理軟體解除安裝,繼續測試,

Bug未解決,該Bug與緩存清理無關

補充說明:

後面交流才知道patch的下載下傳路徑在/data/data/com.axecom.smartweightdj/files/sophix/patch(非系統簽名app的路徑,系統簽名的下載下傳路徑我也沒權限看不到啊)。

2. MultiDex不正常

各種日志分析測試,發現apk中有多個.dex檔案,懷疑MultiDex失敗的問題。我的apk中有7個.dex檔案,後面幾個.dex檔案方法數隻有幾百個。 一般來說隻有方法數超過65535,才會有兩個.dex檔案,後面依次計算,超過65535*2才會有3個.dex檔案。

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

技術支援小哥讓我生成正常的apk,這可難倒我了,找不出我的apk生成多個.dex檔案的原因,,我隻能笨辦法,重建工程把内容以過去,好了,發現apk正常了,隻有了2個.dex檔案。

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結
熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結
熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

滿心歡喜的以為搞定了,測試看看。我去,

bug還是沒解決,依然存在

3. System.exit(0)

繼續測試找背鍋俠。在關閉的過程中,有System.exit(0)這個操作,好吧會不會是它造成的,我猜一般應該和這個沒關系吧。

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

果然屏蔽了System.exit(0)方法後,Bug還是沒有解決。繼續其他猜想。

關于System.exit(0) 與 android.os.Process.killProcess(android.os.Process.myPid())的使用和差別,請檢視我其他部落格的分析介紹。

部落格位址待補充,文章已寫完還未釋出

4. patch更新檔是否加載正常

沒辦法,同樣一個更新檔,Sophix是不會不斷下載下傳同一更新檔的,那麼實時觀察它的狀态吧。

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

此時不嘗試獲得兩個總結:

1.

為了能看到data\data\package中的patch檔案,我取消了系統簽名,發現更新檔竟然成功了。

2.

非系統簽名app,如果系統未root,一般也看不到data\data\package中的資訊,此時隻能通過配置debuggable true,此時我們能通過 看到data\data\package中的資料。

意外驚喜是非系統簽名的app debuggable=true時, 更新檔能正常。此時能看到data\data\package中的内容

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

趕緊測試debuggable=false時,更新檔也能正常。此時權限問題無法看到data\data\package中的内容

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

在這裡插入圖檔描述

3

我的bug造成的原因肯定和系統簽名有關系

5. 系統權限

通過長長的詳細Verbose級日志,分析到:

合成的更新檔 ,新的更新檔加載可以成功,合成的更新檔 拒絕執行denied execute

。如果apk不經系統簽名,不會有該問題,是以定位可定是系統權限哪裡的問題。

我們使用Android studio能看到的日志條數一般是有限制的,為了不得漏掉日志,建議使用 adb log技術,使用如: adb logcat -s :V > d:/999.log 。詳細使用方式網上搜尋會更詳細。

經過努力已經查找出system app進行Sophix熱更新的更新檔反複失效的原因,這和系統權限确實有關系,将enforce設定為0 ,也就是降低Android系統的一些安全要求,放款權限限制。

通過對比system app 和普通app的sophix的patch更新檔檔案夾。

system app

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

如下是普通app的

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

此時你會發現兩者的RW權限是一樣的,patch也從背景下載下傳了。但是最終System app不能成功,是因為系統的安全限制作怪,設定setenforce 0即可解決問題。

注意:System App的目錄我們看不到,可以通過adb shell 進入通過shell指令檢視檔案夾詳細資訊

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

問題解決:

bug源碼解決了。這個bug折磨了我一個周的時間去整理和排除,可謂是傷透了心。

我的這個Bug一般人是碰不到的,需要系統簽名的軟體才會碰到如此問題,希望你們不會碰到,截止20200516,我所知道能讓系統簽名的app也支援Sophix的隻有讓Android 系統 setenforce 0 降低安全标準了。

坑三:abandon initialization: callRealAppAttach

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

這種問題比較簡單,在低Android系統中,當Apk中的方法數量超過限制時,就需要使用MultiDex技術。該處報錯就是因為未配置MultiDex.install(this), SophixStubApplication和RealApplication兩個Application沒在一個dex中引起的,隻要正确配置即可解決。

​​

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結
熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

注意這個問題的 MultiDex.install(this)要在SophixStubApplication.java檔案中,其他Application中不得有 MultiDex.install(this)。

小結

  1. 其實生成了多個.dex的原因是:設定了 debuggable= true,此時生成了7個.dex檔案,debuggable= false時生成的apk有2個.dex檔案。
  2. 這個Bug其實與debuggable的設定其實毫無關系,也即與.dex的多寡無關。這是後面經過我多次測試終于明白的。`**
  3. 碰到技術bug能耐下心來去研究,排查,網上搜資料,始終能解決問題的。
  4. 我的這個Bug的唯一解決方式是系統要root,或者将patch下載下傳到外部空間如public\download中(

    但是Sophix現在是不支援修改設定patch下載下傳位址的

    )

補充知識

1. enforce

**enforce:**加強,這裡指 security enforce安全加強,也就是SELinux,setenforce 0就是表示關閉SELinux(Linux的防火牆)的加強模式

當我們設定setenforce 0 後,可以通過shell 指令getenforce可以看到設定狀态。顯示permissive即為防火牆關閉了。

熱更新Sophix的爬坑之路前言坑一:AndroidX 不相容坑二:patch 更新檔反複失效坑三:abandon initialization: callRealAppAttach補充知識總結

0: 切換成 permissive(寬容模式)

1: 切換成 enforcing(強制模式)

2. Root

Android系統本質就是一個Linux 系統,Linux系統的強大在于多使用者管理,對于不同的使用者給不同的權限,Linux系統裡面有一個超級使用者,叫做su。

如果你能擷取su使用者執行的指令,那你就獲得了超級使用者權限。對于系統自帶的檔案和apk可見,并且能進行删除和修改操作。

總結

  • 首先要感謝自己的持之以恒,碰到的bug和爬坑過程,時間跨度在一個星期和一個多月。中間要做各種測試操作和驗證,補充相關論點支援,每次自己都未有想放棄的想法,雖然頭疼還是堅持排查最終也得到了解決。
  • 非常感謝Sophix的技術支援@塗中和@徐厚、@劉寶文,這些Sophix的技術支援團隊非常的有耐心,對于技術疑惑回答都很及時且對提問者的問題都是有問必答比解決。非常敬佩他們的敬業精神,果然覺得阿裡的招牌不是蓋的。
  • 我在熱更新方向是從Bugly平台轉到EMAS的,兩者的技術高低暫且不論,技術支援方面是高低立下的,真的建議大家更偏向Sophix,少踩Bugly的坑,在我的博文《熱更新你都知道哪些?》會分析為什麼優先使用Sophix 。

相關連結:

  1. 熱更新你都知道哪些?
  2. 熱更新Sophix的爬坑之路
  3. 騰訊熱更新Tinker的故事
  4. 阿裡熱更新Sophix的故事

擴充連結:

  1. ART與Dalvik、JVM之間的關系你懂了嗎?
  2. System.exit(0) 與 android.os.Process.killProcess(android.os.Process.myPid())

部落格書寫不易,您的點贊收藏是我前進的動力,千萬别忘記點贊、 收藏 ^ _ ^ !