Google输入法调用抛出JNI错误

  这两天在调查ICS中Google输入法crash的问题。

 

  首先调查到原因是:libjni_pinyinime.so已生成在“¥OUT/obj/SHARED_LIBRARIES/”下,但没有打包到system.img中。

  解决这个问题的方法是:在Andriod.mk指定依赖关系,指定PinyinIME.apk依赖于libjni_pinyinime.so。

  在packages/inputmethods/PinyinIME/Android.mk中添加:

LOCAL_REQUIRED_MODULES := libjni_pinyinime


 解决了以上问题后,在eng版本中Google输入法可以使用了,但在userdebug版本中仍然会crash。经调查,两个版本生成的apk大小不一致,userdebug版要比eng版小100多B。log输出如下:

I/ActivityManager(  405): Start proc com.android.inputmethod.pinyin for service com.android.inputmethod.pinyin/.PinyinIME: pid=2093 uid=10064 gids={3003}
D/GpsLocationProvider(  405): Gps MessageHandler. msg.what 12
D/GpsLocationProvider(  405): handleNativePhoneContextUpdate called. updateType: 2 mRequestContextType: 0 mRequestType: 0
D/GpsLocationProvider(  405): handleNativePhoneContextUpdate. Update obtained before request. Ignoring
D/memalloc(  405): /dev/pmem: Unmapping buffer base:0x57dcc000 size:13025280 offset:12226560
D/memalloc(  141): /dev/pmem: Freeing buffer base:0x42cc9000 size:798720 offset:12226560 fd:34
D/memalloc(  405): /dev/pmem: Unmapping buffer base:0x57a1b000 size:3870720 offset:3072000
E/dalvikvm( 2093): ERROR: couldn't find native method
E/dalvikvm( 2093): Requested: Lcom/android/inputmethod/pinyin/PinyinDecoderService;.nativeImOpenDecoder:([B[B)Z
W/dalvikvm( 2093): JNI_OnLoad returned bad version (-1) in /system/lib/libjni_pinyinime.so 0x41591d90
E/PinyinDecoderService( 2093): WARNING: Could not load jni_pinyinime natives
W/dalvikvm( 2093): No implementation found for native Lcom/android/inputmethod/pinyin/PinyinDecoderService;.nativeImOpenDecoderFd (Ljava/io/FileDescriptor;JJ[B)Z
W/dalvikvm( 2093): threadid=1: thread exiting with uncaught exception (group=0x40c3c1f8)
D/memalloc(  141): /dev/pmem: Freeing buffer base:0x4240e000 size:798720 offset:3072000 fd:31
E/AndroidRuntime( 2093): FATAL EXCEPTION: main
E/AndroidRuntime( 2093): java.lang.UnsatisfiedLinkError: nativeImOpenDecoderFd
E/AndroidRuntime( 2093):     at com.android.inputmethod.pinyin.PinyinDecoderService.nativeImOpenDecoderFd(Native Method)
E/AndroidRuntime( 2093):     at com.android.inputmethod.pinyin.PinyinDecoderService.initPinyinEngine(PinyinDecoderService.java:141)
E/AndroidRuntime( 2093):     at com.android.inputmethod.pinyin.PinyinDecoderService.onCreate(PinyinDecoderService.java:162)
E/AndroidRuntime( 2093):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2253)
E/AndroidRuntime( 2093):     at android.app.ActivityThread.access$1600(ActivityThread.java:123)
E/AndroidRuntime( 2093):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201)
E/AndroidRuntime( 2093):     at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 2093):     at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime( 2093):     at android.app.ActivityThread.main(ActivityThread.java:4424)
E/AndroidRuntime( 2093):     at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 2093):     at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime( 2093):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:787)
E/AndroidRuntime( 2093):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:554)
E/AndroidRuntime( 2093):     at dalvik.system.NativeStart.main(Native Method)


 在网上搜到了解决方法。

  以下转载自:http://blog.csdn.net/winsonx/article/details/6461810


Google输入法调用抛出JNI错误

分类: Android 116人阅读 评论(0) 收藏 举报

  昨天收到个Bug,是关于Google输入法调用后报异常,Log信息大概是说找不到JNI方法nativeImOpenDecoder(),

后发现在编译此版本系统前的TARGET_BUILD_VARIANT选项是user,和平时用的eng有所不同,重新烧了eng和user版本验证下确实有此问题,刚开始想都没想直接就去看Make脚本了,因为一定有所不同,看了半小时后头昏眼花,最主要是没看太明白,放弃。。。

  后拿来user版和eng版的GooglePinyin.apk比较了下,发现user版的大小少了100多byte,原来缺少代码,网上一顿

搜罗反编译工具,最后确定在PinyinDecoderService.java类里缺少nativeImOpenDecoder()方法,此方法是native方法,所以在加载.so文件时没有找到该方法报出异常,又在项目中查找下引用,才知道整个项目任何并没有调用过此方法,到此可以判断出在编译的时候系统做了优化,把无用的代码做了过滤。好,那我就在编译时强制保留此方法,了解到Android系统编译是用ProGuard来进行代码优化和混淆工作的,OK,参照别的Android.mk文件加了参数:

    LOCAL_PROGUARD_FLAGS := -include $(LOCAL_PATH)/proguard.flags

 

又创建了proguard.flags文件,内容如下:

    -keep class com.android.inputmethod.pinyin.PinyinDecoderService {
    static *;
    }

 

最后重新编译并测试,可成功调用Google输入法。

  总结下,在编译代码过程中ProGuard起了关键作用,所以了解还是非常必要的,特转以下文章地址来学习下:

 

http://www.cnitblog.com/zouzheng/archive/2011/01/12/72639.html



你可能感兴趣的:(exception,android,jni,Google,buffer,输入法,反编译工具)