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.youkuaiyun.com/guolin_blog/article/details/49738023
https://blog.youkuaiyun.com/weixin_34279061/article/details/86056106
https://blog.youkuaiyun.com/u014432674/article/details/42739025?locationNum=5
https://blog.youkuaiyun.com/sinat_14854721/article/details/82836927