前几天,我们在开发中遇到一个问题,起因是这样的:
在Android里使用WebView访问https SSL证书网页,而此网页是有SSL错误,我们需要接受这个错误,代码里是这么写的:
webview.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
// 不要使用super,否则有些手机访问不了,因为包含了一条 handler.cancel()
// super.onReceivedSslError(view, handler, error);
// 接受所有网站的证书,忽略SSL错误,执行访问网页
// 在这里也可以弹出对话框让用户选择是否继续
handler.proceed();
}
}
当时android组的小弟直接就check in代码了,因为他在debug下验证正确了,于是我们编译了Release版本,即Export一个apk给测试组测试,接着发现,根本不可以!就是说,这句根本运行不到。
中间查错的过程略去几百字......
后来发现问题所在:
由于我们工程里包含JNI代码,即工程中含有代码混淆配置文件,使得我们使用的API在发布版本中也被混淆掉了,所以导致在Release版本中无法使用,正确做法是在proguard.cfg 中加上:
-keep class android.net.http.SslError
意思是保持class android.net.http.SslError类和所有方法而不混淆。
同样,我们也可以加入某些自定义类,不让混淆:
-keepclassmembers public class com.xxx.xxx.MyKeepActivity {
*;
}
测试之后,果然可以了,这下android组小弟终于能愉快的下班了。
大家以后遇到这类问题,可以先往代码混淆这个地方考虑。
最后,附录关于代码混淆语法内容:
keep 保持类类成员(Classes and class members)
keepclassmembers 仅保持类成员(Class members only)
keepclasseswithmembernames 保持类和类成员,如果类成员存在(Classes and class members, if class members present)
keepattributes 保留部分属性
每个这些-keep后跟确定的类和类成员的说明(字段和方法),其应该被应用。
如果你不知道你需要的选项,你应该简单地使用-keep。这将确保指定的类和类成员在收缩步骤不会被删除,并且在混淆步不改名。