andfix 多次修改同一個(gè)方法報(bào)錯(cuò)的解決

關(guān)于andfix 看這

最近主管說要把熱修復(fù)做下蹦锋,組長把任務(wù)交給了我兆沙,那就領(lǐng)命開始干,網(wǎng)上找了幾篇文章學(xué)習(xí)了下莉掂,最后選擇了andfix葛圃。在網(wǎng)上找了幾篇文章學(xué)習(xí)了下,感覺just so so嘛憎妙,我的內(nèi)心開始膨脹(只是滾輪子嘛)库正。
遇到了幾個(gè)問題,5.0以下同一個(gè)方法可以多次修改厘唾,5.0以上不行這個(gè)問題困擾我很久褥符,報(bào)錯(cuò)如下:

Fatal Exception: java.lang.IllegalAccessError: Method 'void com.amour.chicme.activity.MainActivity_CF.q()' is inaccessible to class 'com.amour.chicme.activity.MainActivity_CF' (declaration of 'com.amour.chicme.activity.MainActivity_CF' appears in /data/user/0/com.amour.chicme/files/apatch/572340d6d21e9e13ac2d7556.apatch)
       at com.amour.chicme.activity.MainActivity_CF.onCreate(Unknown Source)
       at android.app.Activity.performCreate(Activity.java:6237)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
       at android.app.ActivityThread.-wrap11(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5417)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

至于為什么報(bào)這個(gè)錯(cuò)誤的原因,不知道抚垃。喷楣。。知道的哥們麻煩告訴我鹤树。
既然不能解決這個(gè)錯(cuò)誤铣焊,那只好繞過這個(gè)坑了,于是我把將patch文件做成最初版本apk和最新修改過的apk對(duì)比生成罕伯,andfix對(duì)外提供了一個(gè)方法patchManager.removeAllPatch()從字面上就能理解這個(gè)方法了曲伊,去除所有的.apatch文件。so追他,在每次下載成功后patchManager.addPatch(target)前我調(diào)用前面的patchManager.removeAllPatch()方面坟募。看起來一切是如此的合理邑狸,此時(shí)的我已經(jīng)膨脹的快要爆炸了懈糯。接下來的結(jié)果讓我很是意外,在修復(fù)當(dāng)前patch文件完成后推溃,再次啟動(dòng)app昂利,最新的已經(jīng)修復(fù)過的patch不再下載和add届腐,此時(shí)沒有進(jìn)行addpatch()操作铁坎,于是app變成了最初的版本蜂奸,沒有任何修復(fù)完成。在我的理解中硬萍,這兩步操作patchManager.removeAllPatch();patchManager.addPatch( target);可以永遠(yuǎn)只保留最后修復(fù)過的那個(gè).apatch文件扩所,就不會(huì)出現(xiàn)多次修改同一個(gè)方法的情況了,看上去完全沒有問題啊朴乖,我迷茫了祖屏。。买羞。我開始意識(shí)到andfix肯定在某個(gè)步驟中將我最后保留的.apatch文件清除了袁勺,我對(duì)著源碼尋尋覓覓,發(fā)現(xiàn)patchManager.removeAllPatch()不僅僅只是清除了.apatch文件畜普,他還清除了當(dāng)前的SharedPreferences文件

public void removeAllPatch() {  
  cleanPatch();   
  SharedPreferences sp = mContext.getSharedPreferences(SP_NAME,   Context.MODE_PRIVATE);   
  sp.edit().clear().commit();
}

于是在init時(shí)

public void init(String appVersion) {
   if (!mPatchDir.exists() && !mPatchDir.mkdirs()) {// make directory fail
      Log.e(TAG, "patch dir create error.");
      return;
   } else if (!mPatchDir.isDirectory()) {// not directory      mPatchDir.delete();
      return;
   }
   SharedPreferences sp = mContext.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
   String ver = sp.getString(SP_VERSION, null);
   if (ver == null || !ver.equalsIgnoreCase(appVersion)) {
      cleanPatch();
      sp.edit().putString(SP_VERSION, appVersion).commit();
   } else {
      initPatchs();
   }
}

獲取到的ver為null期丰,于是我自認(rèn)為能保留下來的.apatch文件也被刪除了。
接下來我采取了如下兩種措施:
1吃挑、不直接調(diào)用removeAllPatch()反射調(diào)用 cleanPatch();
2钝荡、聽取網(wǎng)上哥們的意見,在removeAllPatch()后自己將移除的SharedPreferences 文件保存下來舶衬,將版本號(hào)保存埠通。
最后的結(jié)果還是報(bào)錯(cuò),錯(cuò)誤還是上面列出來的逛犹。
此時(shí)的我有點(diǎn)心累端辱。。好受傷虽画。掠手。
最后和組長討論了下,他說何不自己建立目錄保存.apatch文件呢狸捕?一語驚醒夢(mèng)中人芭绺搿!方案出來了:
1灸拍、在file目錄下建立一個(gè)文件夾保存.apatch文件(ps:andfix就是這么做的),將下載的文件保存在里面做祝。當(dāng)然,文件名要是個(gè)唯一標(biāo)識(shí)鸡岗。

private void uploadFixData(final Hotfix hotfix) {
    File file = new File(getFilesDir(), "hotfix");
    if (!file.exists() && !file.mkdirs()){
        return;
    }
    final String target = file.getAbsolutePath() + "/" + hotfix.id + ".apatch";    
    ConfigManager.getInstance().downloadHotfixFile(hotfix.patchUrl, target, new RequestCallBack<File>() {
        @Override
        public void onSuccess(ResponseInfo<File> responseInfo) {
            try {
                patchManager.removeAllPatch();
                patchManager.addPatch( target);
                SPUtils.save("hotfix", "hotfixID", hotfix.id);
            } catch (Exception e) {
                addLastApatch();
                UIUtils.showToast(e.toString());
                SPUtils.save("hotfix", "hotfixID", "0");
                e.printStackTrace();
            }
        }
        @Override
        public void onFailure(HttpException e, String s) {
            addLastApatch();
        }
    });
}

2混槐、檢查有更新文件時(shí),將先前自己保存的文件刪除轩性,再去下載文件声登。保證只保留一個(gè)文件,多的浪費(fèi)存儲(chǔ)空間。

private void checkAndfixData() {
    ConfigManager.getInstance().getAppHotfixData(new RequestCallBack<String>() {
        @Override
        public void onSuccess(ResponseInfo<String> responseInfo) {
            ResponseUtils responseUtils = new ResponseUtils(responseInfo.result);
            if (responseUtils.isSuccess()) {
                Hotfix hotfix = responseUtils.onSuccessModel(Hotfix.class);
                String existId = SPUtils.getString("hotfix", "hotfixID");                if (hotfix == null || TextUtils.isEmpty(hotfix.id)) {
                    return;
                } else if (hotfix != null && !hotfix.id.equals(existId)) {                                       
                    File file = new File(getFilesDir(), "hotfix");
                    if (file.exists()){
                        file.delete();
                    } 
                   uploadFixData(hotfix);
                } else {
                    addLastApatch();
                }
            } else {
                String existId = SPUtils.getString("hotfix", "hotfixID");
                if (!TextUtils.isEmpty(existId)) {
                    addLastApatch();
                }
            }
        }
        @Override
        public void onFailure(HttpException e, String s) {           
            addLastApatch();
        }
    });
}

3悯嗓、addLastApatch()的實(shí)現(xiàn)很簡單件舵。在檢查更新時(shí)如果沒有更新就直接加載最后保留的那個(gè),當(dāng)然本身就沒有更新文件脯厨,那就不用加載铅祸,可以通過查看保留的唯一標(biāo)識(shí)來判斷。

private void addLastApatch() {
    try {
        File file = new File(getFilesDir(), "hotfix");
        if (!file.exists()){
            return;
        }
      String lastApatchPath = file.getAbsolutePath() + "/" + SPUtils.getString("hotfix", "hotfixID") + ".apatch";
      patchManager.addPatch(lastApatchPath);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

至此合武,問題解決了临梗。試過三星NOTE3,紅米note2稼跳,nexus 5盟庞,LG,沒有問題汤善,其他的沒有試過什猖,因?yàn)闆]有手機(jī)。萎津。卸伞。
希望這篇文章能幫助到你,當(dāng)然你不想修復(fù)多次锉屈,也就沒有這個(gè)問題了荤傲,前面說了一堆廢話,只是想發(fā)泄一下(還可以籌字?jǐn)?shù)颈渊。遂黍。。俊嗽。嘎嘎)雾家。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市绍豁,隨后出現(xiàn)的幾起案子芯咧,更是在濱河造成了極大的恐慌,老刑警劉巖竹揍,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件敬飒,死亡現(xiàn)場離奇詭異,居然都是意外死亡芬位,警方通過查閱死者的電腦和手機(jī)无拗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事〗粘冢” “怎么了四康?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵搪搏,是天一觀的道長。 經(jīng)常有香客問我箭养,道長慕嚷,這世上最難降的妖魔是什么哥牍? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任毕泌,我火速辦了婚禮,結(jié)果婚禮上嗅辣,老公的妹妹穿的比我還像新娘撼泛。我一直安慰自己,他們只是感情好澡谭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布愿题。 她就那樣靜靜地躺著,像睡著了一般蛙奖。 火紅的嫁衣襯著肌膚如雪潘酗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天雁仲,我揣著相機(jī)與錄音仔夺,去河邊找鬼。 笑死攒砖,一個(gè)胖子當(dāng)著我的面吹牛缸兔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吹艇,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼惰蜜,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了受神?” 一聲冷哼從身側(cè)響起抛猖,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鼻听,沒想到半個(gè)月后财著,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡精算,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年瓢宦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片灰羽。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡驮履,死狀恐怖鱼辙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情玫镐,我是刑警寧澤倒戏,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站恐似,受9級(jí)特大地震影響杜跷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜矫夷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一葛闷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧双藕,春花似錦淑趾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嘶摊,卻和暖如春延蟹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背叶堆。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來泰國打工阱飘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蹂空。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓俯萌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親上枕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子咐熙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,095評(píng)論 25 707
  • 前言 熱修復(fù)也叫熱更新,又叫做動(dòng)態(tài)加載辨萍、動(dòng)態(tài)修復(fù)棋恼、動(dòng)態(tài)更新,是指不通過重新安裝新的APK安裝包的情況下修復(fù)一些線上...
    小楠總閱讀 1,613評(píng)論 11 10
  • 項(xiàng)目以飛快的速度迭代锈玉,2周進(jìn)行一次迭代升級(jí)爪飘。每次開發(fā)完功能跑通,在現(xiàn)有機(jī)型上測(cè)試沒問題的話拉背,就提交市場师崎。 在以極快...
    張庚閱讀 6,879評(píng)論 3 18
  • 現(xiàn)在越來越覺得自己做錯(cuò)太多,當(dāng)那一刻來臨椅棺,我無能為力的時(shí)候犁罩,心里只有痛和愧疚齐蔽,您慢慢地意識(shí)模糊,眼睛迷蒙床估,我...
    慕雨蝶閱讀 219評(píng)論 0 0
  • 沉默是魔鬼 永遠(yuǎn)沉默下去 在黑暗里開出一朵美麗的花 在漆黑的風(fēng)中搖曳 獨(dú)自芬芳 這朵花的名字叫默 獨(dú)自沉默
    張琬琪_閱讀 121評(píng)論 0 0