数千名客户中有一位在我的某个应用中报告错误。错误是:
java.lang.NoClassDefFoundError - android.security.MessageDigest
我不在我的应用中使用该类/方法。谷歌Mapkey必须是好的,因为有数千个人使用相同的版本快乐地运行相同的应用程序。这是堆栈跟踪:
java.lang.NoClassDefFoundError: android.security.MessageDigest
at com.google.android.maps.KeyHelper.getSignatureFingerprint(KeyHelper.java:60)
at com.google.android.maps.MapActivity.createMap(MapActivity.java:552)
at com.google.android.maps.MapActivity.onCreate(MapActivity.java:422)
at xx.yyy.zzzz.MyMapActivity.onCreate(MyMapActivity.java:41)
at xx.yyy.zzzz.TheMap.onCreate(TheMap.java:89)
at android.app.Activity.performCreate(Activity.java:4465)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
at android.app.ActivityThread.access$600(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
这是什么?
提前致谢。
答案 0 :(得分:20)
我花了一些时间来研究这个问题,我正在记录我在这里找到的东西,希望能为其他人省去一些麻烦。
错误是设备制造商或ROM创建者使用旧版地图库和新版Android的结果。通常情况下,这是孤立的模糊片剂,但它理论上可以出现在其他情况下。可以使用以下步骤在模拟器中重新创建此问题:
adb pull /system/framework/com.google.android.maps.jar <destination_folder>
完成此操作后,您可以关闭模拟器。adb remount
adb push <destination_folder>/com.google.android.maps.jar /system/framework
adb reboot
可行的,但只是挂起了模拟器。相反,您需要杀死具有相同效果的特定进程。在Eclipse / DDMS中,它将被称为system_process
,你可以在那里杀死它。或者,您可以运行此命令:adb shell ps | grep system_server | awk '{print $2}' | xargs adb shell kill
此过程不是永久性的。重新启动仿真器会将其恢复到正常工作状态。
可以通过反射调用地图库中的KeyHelper.getSignatureFingerprint()
方法并调用它来检测此问题 - 将PackageManager
和您的包名称作为参数传递。或者,您可以在onCreate()
中捕获错误并改为加载新活动。
答案 1 :(得分:9)
MessageDigest类是一个辅助类,用于使用常见方法(如MD5或SHA-1)对密钥进行编码/解码。
似乎android.security.MessageDigest类已从Honeycomb及更高版本的Android中删除,必须替换为java.security.MessageDigest(see this page)
尝试下载最新版本的Google Maps API并重新设置应用程序,并将targetSDK设置为可用的最高版本(截至今日它应为16 / Jelly Bean)。
答案 2 :(得分:9)
我找到了简单的解决方法!只需在src目录包中创建android \ security并将MessageDigest.java放在里面。
package android.security;
import java.security.NoSuchAlgorithmException;
public class MessageDigest
{
private java.security.MessageDigest instance;
public MessageDigest() {}
private MessageDigest(java.security.MessageDigest instance)
{
this.instance = instance;
}
public static MessageDigest getInstance(String algorithm) throws NoSuchAlgorithmException
{
if (algorithm == null) return null;
try
{
if (algorithm.equals("SHA-1"))
return (MessageDigest) Class.forName("android.security.Sha1MessageDigest").newInstance();
else if (algorithm.equals("MD5"))
return (MessageDigest) Class.forName("android.security.Md5MessageDigest").newInstance();
}
catch (Exception e) {}
return new MessageDigest(java.security.MessageDigest.getInstance(algorithm));
}
public void update(byte[] input)
{
instance.update(input);
}
public byte[] digest()
{
return instance.digest();
}
public byte[] digest(byte[] input)
{
return instance.digest(input);
}
}
这是有效的,但由于地图库不匹配Android版本,可能会产生其他异常!