您好,登錄后才能下訂單哦!
這篇“Android中怎么手寫熱修復(fù)dex”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Android中怎么手寫熱修復(fù)dex”文章吧。
當(dāng)前ClassLoader首先從自己已經(jīng)加載的類中查詢是否此類已經(jīng)加載,如果已經(jīng)加載則直接返回原來已經(jīng)加載的類。 每個類加載器都有自己的加載緩存,當(dāng)一個類被加載了以后就會放入緩存,等下次加載的時候就可以直接返回了。
當(dāng)前classLoader的緩存中沒有找到被加載的類的時候,委托父類加載器去加載,父類加載器采用同樣的策略,首先查看自己的緩存,然后委托父類的父類去加載,一直到bootstrp ClassLoader.
當(dāng)所有的父類加載器都沒有加載的時候,再由當(dāng)前的類加載器加載,并將其放入它自己的緩存中,以便下次有加載請求的時候直接返回。
突破口來了,看1(如果已經(jīng)加載則直接返回原來已經(jīng)加載的類) 對于同一個類,如果先加載修復(fù)的類,當(dāng)后續(xù)在加載未修復(fù)的類的時候,直接返回修復(fù)的類,這樣bug不就解決了嗎?
Nice ,多看源碼和jvm 許多問題可以從framework和底層去解決
public class InitActivity extends FragmentActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //這里默認(rèn)在SD卡根目錄,實際開發(fā)過程中可以把dex文件放在服務(wù)器,在啟動頁下載后加載進來 //第二次進入的時候可以根據(jù)目錄下是否已經(jīng)下載過,處理,避免重新下載 //最后根據(jù)當(dāng)前app版本下載不同的修復(fù)dex包 等等一系列處理 String dexFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/fix.dex"; DexFile dexFile = null; try { dexFile = DexFile.loadDex(dexFilePath, null, Context.MODE_PRIVATE); } catch (IOException e) { e.printStackTrace(); } patchDex(dexFile); startActivity(new Intent(this, MainActivity.class)); } /** * 修復(fù)過程,可以放在啟動頁,這樣在等待的過程中,網(wǎng)絡(luò)下載修復(fù)dex文件 * * @param dexFile */ public void patchDex(DexFile dexFile) { if (dexFile == null) return; Enumeration<String> enumeration = dexFile.entries(); String className; //遍歷dexFile中的類 while (enumeration.hasMoreElements()) { className = enumeration.nextElement(); //加載修復(fù)后的類,只能修復(fù)當(dāng)前Activity后加載類(可以放入Application中執(zhí)行) dexFile.loadClass(className, getClassLoader()); } } }
方法很簡單在啟動頁,或者Application中提前加載有bug的類
這里寫的很簡單,只是展示核心代碼,實際開發(fā)過程中,dex包下載的網(wǎng)絡(luò)請求,據(jù)當(dāng)前app版本下載不同的修復(fù)dex,文件存在的時候可以在Application中先加載一次,啟動頁就不用加載,等等,一系列優(yōu)化和判斷處理,這里就不過多說明,具體一些處理看github上的代碼
###ok 代碼都了解了,這個 fix.dex
文件哪里來的呢 熟悉Android apk生成的小伙伴都知道了,跳過這個步驟,不懂的小伙伴繼續(xù)往下看
上面的InitActivity
中startActivity(new Intent(this, MainActivity.class));
啟動了一個MainActivity
看看我的MainActivity
public class MainActivity extends FragmentActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //0不能做被除數(shù),這里會報ArithmeticException異常 Toast.makeText(this, "結(jié)果" + 10 / 0, Toast.LENGTH_LONG).show(); } }
哎呀不小心,寫了一個bug 0 咋能做除數(shù)呢,app已經(jīng)上線了,這里必崩啊,咋辦 不要急,按照以下步驟:
我們要修復(fù)這個類MainActivity
,先把bug解決
Toast.makeText(this, "結(jié)果" + 10 / 2, Toast.LENGTH_LONG).show();
把修復(fù)類生成.class
文件(可以先run一次,之后在 build/intermediates/javac/debug/classes/com開的的文件夾,找到生成的class文件,也可以通過javac 命令行生成,也可以通過右邊的gradle Task生成)
把修復(fù)類.class
文件 打包成dex (其他.class
刪除,只保留修復(fù)類) 打開cmd命令行,輸入下面命令
D:\Android\sdk\build-tools\28.0.3\dx.bat --dex --output C:\Users\pei\Desktop\dx\fix.dex C:\Users\pei\Desktop\dx\
D:\Android\sdk
為自己sdk目錄 28.0.3
為build-tools
版本,可以根據(jù)自己已經(jīng)下載的版本更換 后面兩個目錄分別是生成.dex
文件目錄,和.class
文件目錄
切記 .class
文件的目錄必須是包名一樣的,我的目錄是 C:\Users\pei\Desktop\dx\com\pei\test\MainActivity.class
,不然會報 class name does not match path
這樣dx文件夾下就會生成fix.dex文件了,把fix.dex放進手機根目錄試試吧
再次打開App,完美Toast 結(jié)果5,完美解決
以上就是關(guān)于“Android中怎么手寫熱修復(fù)dex”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。