Android apk运行时错误java.lang.NoSuchMethodError: com.google.gson.GsonBuilder.setLenient

最近在Hisi3751V500上移植一个新的项目,在运行gitv牌照方apk的时候提示java.lang.NoSuchMethodError: com.google.gson.GsonBuilder.setLenient

06-03 17:44:28.966 I/dalvikvm( 3617): Could not find method com.google.gson.GsonBuilder.setLenient, referenced from method com.gitv.tv.launcher.utils.RetrofitFactory.create
06-03 17:44:28.966 W/dalvikvm( 3617): VFY: unable to resolve virtual method 39078: Lcom/google/gson/GsonBuilder;.setLenient ()Lcom/google/gson/GsonBuilder;
06-03 17:44:28.966 D/dalvikvm( 3617): VFY: replacing opcode 0x6e at 0x0007
06-03 17:44:28.970 D/AndroidRuntime( 3617): Shutting down VM
06-03 17:44:28.970 W/dalvikvm( 3617): threadid=1: thread exiting with uncaught exception (group=0x41724ba8)
06-03 17:44:28.976 E/AndroidRuntime( 3617): FATAL EXCEPTION: main
06-03 17:44:28.976 E/AndroidRuntime( 3617): Process: com.gitv.tv.launcher, PID: 3617
06-03 17:44:28.976 E/AndroidRuntime( 3617): java.lang.NoSuchMethodError: com.google.gson.GsonBuilder.setLenient
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at com.gitv.tv.launcher.utils.RetrofitFactory.create(RetrofitFactory.java:68)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at com.gitv.tv.launcher.utils.RetrofitFactory.create(RetrofitFactory.java:36)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at com.gitv.tv.launcher.data.DataManager.getIP(DataManager.java:708)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at com.gitv.tv.launcher.service.task.SettingTask.getIP(SettingTask.java:105)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at com.gitv.tv.launcher.service.task.SettingTask.init(SettingTask.java:69)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at com.gitv.tv.launcher.application.GitvLauncherApplication.init(GitvLauncherApplication.java:91)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at com.gitv.tv.launcher.application.GitvLauncherApplication.onCreate(GitvLauncherApplication.java:60)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4366)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at android.app.ActivityThread.access$1500(ActivityThread.java:135)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at android.os.Handler.dispatchMessage(Handler.java:102)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at android.os.Looper.loop(Looper.java:136)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at android.app.ActivityThread.main(ActivityThread.java:5039)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at java.lang.reflect.Method.invokeNative(Native Method)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at java.lang.reflect.Method.invoke(Method.java:515)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:736)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:552)
06-03 17:44:28.976 E/AndroidRuntime( 3617):     at dalvik.system.NativeStart.main(Native Method)
06-03 17:44:28.978 W/ActivityManager( 2022):   Force finishing activity com.gitv.tv.launcher/.activity.GitvInterfaceActivity

考虑到这个apk在Hisi3798M,AmlogicS905,Amlogic8726MX上面能正常运行,于是把apk进行反编译,发现apk存在classes.dex及classes2.dex,并且classes.dex里面存在com.google.gson.GsonBuilder.setLenient这个方法,第一反应是Hisi3751V500上面对apk分包机制支持不够,导致方法未加载上,但是折腾了一两天也证明不了分包机制的问题。于是把着重点放到了apk安装的日志上面:

`06-06 15:24:17.467 D/dalvikvm( 5507): DexOpt: not verifying/optimizing 'Lcom/google/gson/GsonBuilder;': multiple definitions`

注意到系统提示multiple definitions,证明GsonBuilder这个classes类跟系统某个classes类版本冲突,因此在系统的ext.jar包导入一个包含GsonBuilder的setLenient方法的google gson的gson-2.6.2.jar包,方法是在$SDK根目录/frameworks/opt/ 目录下新建一个gson的目录,然后把gson-2.6.2.jar包放入到gson目录,写一个Android.mk文件,然后再gson目录下mm编译。Android.mk文件内容:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_JAVA_LIBRARIES := gson
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := gson:gson-2.6.2.jar

include $(BUILD_MULTI_PREBUILT)

然后进入到$SDK根目录/frameworks/base/目录,修改系统Android.mk目录,修改内容如下:

# ====  the library  =========================================
include $(CLEAR_VARS)

LOCAL_SRC_FILES := $(ext_src_files)

LOCAL_NO_STANDARD_LIBRARIES := true
LOCAL_JAVA_LIBRARIES := core
LOCAL_JAVA_RESOURCE_DIRS := $(ext_res_dirs)
#以下这行是新增内容
LOCAL_STATIC_JAVA_LIBRARIES := gson
#以上这行是新增内容
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := ext

LOCAL_DX_FLAGS := --core-library

修改完成后,在$SDK根目录/frameworks/base/目录进行mm编译,编译OK后,替换ext.jar包,已经修正了这个gson的错误。
但是此时apk又报其他错误,正是由于这个错误,让我对于之前gson的版本冲突的判断产生了怀疑:

06-06 18:20:29.795 E/AndroidRuntime( 3060): FATAL EXCEPTION: pool-3-thread-1
06-06 18:20:29.795 E/AndroidRuntime( 3060): Process: com.gitv.tv.launcher, PID: 3060
06-06 18:20:29.795 E/AndroidRuntime( 3060): java.lang.NoSuchMethodError: no static or non-static method "Lcom/facebook/imagepipeline/nativecode/WebpTranscoder;.nativeTranscodeWebpToJpeg(Ljava/io/InputStream;Ljava/io/OutputStream;I)V"
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at java.lang.Runtime.nativeLoad(Native Method)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at java.lang.Runtime.doLoad(Runtime.java:421)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at java.lang.Runtime.loadLibrary(Runtime.java:362)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at java.lang.System.loadLibrary(System.java:526)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at com.facebook.common.soloader.SoLoaderShim$DefaultHandler.loadLibrary(SoLoaderShim.java:32)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at com.facebook.common.soloader.SoLoaderShim.loadLibrary(SoLoaderShim.java:56)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at com.facebook.imagepipeline.nativecode.ImagePipelineNativeLoader.load(ImagePipelineNativeLoader.java:48)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at com.facebook.imagepipeline.memory.NativeMemoryChunk.<clinit>(NativeMemoryChunk.java:36)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at com.facebook.imagepipeline.memory.NativeMemoryChunkPool.alloc(NativeMemoryChunkPool.java:60)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at com.facebook.imagepipeline.memory.NativeMemoryChunkPool.alloc(NativeMemoryChunkPool.java:22)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at com.facebook.imagepipeline.memory.BasePool.get(BasePool.java:260)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at com.facebook.imagepipeline.memory.NativePooledByteBufferOutputStream.<init>(NativePooledByteBufferOutputStream.java:53)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at com.facebook.imagepipeline.memory.NativePooledByteBufferFactory.newByteBuffer(NativePooledByteBufferFactory.java:100)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at com.facebook.imagepipeline.memory.NativePooledByteBufferFactory.newByteBuffer(NativePooledByteBufferFactory.java:28)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at com.facebook.imagepipeline.cache.BufferedDiskCache.readFromDiskCache(BufferedDiskCache.java:341)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at com.facebook.imagepipeline.cache.BufferedDiskCache.access$400(BufferedDiskCache.java:38)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at com.facebook.imagepipeline.cache.BufferedDiskCache$2.call(BufferedDiskCache.java:185)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at com.facebook.imagepipeline.cache.BufferedDiskCache$2.call(BufferedDiskCache.java:168)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at bolts.Task$4.run(Task.java:357)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
06-06 18:20:29.795 E/AndroidRuntime( 3060):     at java.lang.Thread.run(Thread.java:841)
06-06 18:20:29.801 W/ActivityManager( 2042):   Force finishing activity com.gitv.tv.launcher/.activity.PlayActivity

以为是跟gson同样的错误,然后按照gson导入facebook的imagepipeline包发现又报facebook的common类未找到错误,继续导入,发现又有新的错误,此时又回到了起点,以为是Multidex分包的问题,折腾了好久,然后发现系统里面某一个so库跟facebook的libimagepipeline.so重名,编译的时候gitv的牌照方apk的so库被覆盖掉了,替换回gitv的libimagepipeline.so库,一切正常,OK终于搞定了这个问题。

在调试的时候其实也仔细看了上面报错的log,提示com.facebook.imagepipeline.nativecode.ImagePipelineNativeLoader.load错误,当时第一反应是so库被覆盖了,然后一股脑把gitv的so全部导入到系统/system/lib/目录,结果悲剧的是系统死机了(⊙﹏⊙)!,估计是某一个so库覆盖了系统的一个很重要的so导致系统死机了。胜利的曙光又被这次死机拖延了好久,直到后来发现pm安装这个apk系统不会报错,然后再参考上面的log,这次只替换了gitv的一个so库,libimagepipeline.so,终于结束了这几天蛋疼的调试之旅。。。

最终结论,这几天折腾的根源是两个问题导致的:
1. gson版本跟系统某一个apk的gson版本不一致,并且系统这个gson库不包含GsonBuilder的setLenient方法
2. gitv apk的libimagepipeline.so库跟系统某一个apk的so库冲突,在loadlibrary的时候报错,导致gitv闪退

猜你喜欢

转载自blog.csdn.net/email_jade/article/details/72886991