9102年的10月29號下午,我美滋滋的從wc回來。然後,被告知需要緊急上線一個版本。由於公司有一個域名出現了問題,有些配置需要修改。尷尬了,因爲來公司一年一直都是按時迭代,沒有出現過這種緊急情況。所以我最近兩個版本上線後沒有及時把代碼推送到git。還有一個原因就是這個版本測試中,需要做下個版本需求。切換分支太煩,所以哈哈哈。。。常在河邊走,記得常換鞋。一定要記得及時提交代碼。。。
我AS上的代碼已經改了很多了,註釋代碼不可能了。所以,我想到了反編譯線上的apk。在這和大家分享一下。
我們需要做的步驟:
1. 將線上apk反編譯;
2. 將我的配置路徑修改;
3. 修改版本號;
4. 將修改完的代碼,二次打包,簽名上線;
Demo:
1.寫一個根目錄類:
public class Constant {
//根目錄
public static String Host_Url = "www.baidu.com/";
}
2. xml佈局就一個textview展示版本號和根目錄,便於比較:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#3333" />
</RelativeLayout>
3. java 類如下:
// 包管理器 可以獲取清單文件信息
PackageManager packageManager = getPackageManager();
try {
// 獲取包信息
// 參1 包名 參2 獲取額外信息的flag 不需要的話 寫0
PackageInfo packageInfo = packageManager.getPackageInfo(getPackageName(), 0);
((TextView) findViewById(R.id.text_id)).setText(packageInfo.versionCode + "\n" + Constant.Host_Url);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
4. apk展示:(地址我們就要百度的地址了)
接下來按步驟一個個做:
一:反編譯APK
反編譯常用的三款工具:
1. dex2jar : 這個工具將dex文件轉換爲jar包;
下載地址:http://sourceforge.net/projects/dex2jar/files/
2. jd-gui: 將jar包轉換成我們平時看的jar文件;
下載地址:http://jd.benow.ca/
3. ApkTool:主要解碼資源文件,代碼會解析成smali文件
下載地址:http://ibotpeaches.github.io/Apktool/install/
很明顯,我們對自己的代碼還是比較熟悉的,不需要用前兩個工具。我們只需要用Apktool就可以了, ApkTool下載好主要是兩個文件 :
把apk放在同一個文件夾下,在這個文件夾下cmd:
appktool d apk文件.apk
一頓操作之後,文件夾下會多出一個和apk同名的文件夾如下:
original : 沒有反編譯的文件 ; res 反編譯後的資源文件 ; smali 代碼被反編譯成 smali 文件 ;apktool.yml 版本號等存放的文件。
二: 修改代碼:
我們進入smali文件,文件夾中還有有的依賴包的反編譯文件。但是,我們的代碼目錄沒有變。找到Constant.smali文件,打開看看:
雖然我們不懂smali文件,但是我們可以看到字符串”www.baidu.com“,將百度改成"www.csdn.cn"。所以,我們這種方法適合改動不大的緊急上線。當然,你懂smali的話就不說了。
三:修改版本號
上線肯定得修改版本號,打開apktool.yml文件。
滑到最下面看到versionCode,根據自己公司的版本約定修改一下。我們在這修改成 1001。
四:再打包和簽名
apktool b 需要打包的文件夾名稱.apk -o 生成的apk名稱.apk
這裏b是build的意思,文件中會出現你命名的apk。這時還不能上線,需要用密鑰簽名才能正式上線。
jarsigner -verbose -keystore 密鑰名稱.jks -signedjar 簽名apk的名稱.apk 目標apk.apk
keyAlias(簽名的別名)
這裏需要將密鑰(.keystore)拷貝過來,輸入上面命令,再輸入密碼即可。jarsigner的命令在jdk的bin目錄下,需要將jdk的bin文件夾地址配置到path環境變量中。
這時候,上線版本就ok了。最終如下:
遇到的問題:
1.ERROR: 9-patch image about.9.png malformed.
這個問題是在apk打包的時候出現的。 原因:我們公司的apk包中有的.9圖只設置了一個邊的約束,apktool工具打包出現了問題。當時想的直接刪除,因爲這個圖沒有用到。所以又出現也下面的問題。
error: Public symbol aaa/bbb declared here is not defined.
很明顯有的定義文件不存在了或者有問題。所以最好解決方法是:我們將.9圖在AS中完善好,再拷貝過來替換現在文件中有問題的.9圖。(ps: 這也說明我們平時及時刪除包中沒必要文件的重要性,即能apk瘦身還能避免不必要的麻煩)。
2.S: WARNING:Could not write to (C:\Users\****\AppData\Local\apktool\framework),
usingC:\Users\*****\AppData\Local\Temp\ instead...
這個問題也是在apktool打包的時候出現的。主要是因爲apktool在反編譯過程中,會在Local\apktool\framework下緩存1.apk文件,但是有些時候會緩存在AppData\Local\Temp中。打包的時候會用到緩存的文件,就會出現問題。
解決方法:打包的時候加上 -p 參數 指定框架資源的路徑(Local\apktool\framework或者AppData\Local\Temp) 。
PS:感謝在下面博客中的收穫
郭霖大神:https://blog.csdn.net/guolin_blog/article/details/49738023
https://blog.csdn.net/weixin_34279061/article/details/86056106
https://blog.csdn.net/u014432674/article/details/42739025?locationNum=5
https://blog.csdn.net/sinat_14854721/article/details/82836927