使用RecyclerView需要注意的版本问题
今天想深入的了解下twoway-view 没想到在运行的时候出现了这个错误(我是用eclipse编译):
04-02 11:12:42.217: D/ContextHelper(32166): convertTheme. context->name=org.lucasr.twowayview.sample themeResourceId=2131427459
04-02 11:12:42.336: D/AndroidRuntime(32166): Shutting down VM
04-02 11:12:42.338: E/AndroidRuntime(32166): FATAL EXCEPTION: main
04-02 11:12:42.338: E/AndroidRuntime(32166): Process: org.lucasr.twowayview.sample, PID: 32166
04-02 11:12:42.338: E/AndroidRuntime(32166): java.lang.RuntimeException: Unable to start activity ComponentInfo{org.lucasr.twowayview.sample/org.lucasr.twowayview.sample.MainActivity}: android.view.InflateException: Binary XML file line #18: Error inflating class org.lucasr.twowayview.widget.TwoWayView
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2306)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2368)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.app.ActivityThread.access$800(ActivityThread.java:149)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.os.Handler.dispatchMessage(Handler.java:102)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.os.Looper.loop(Looper.java:135)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.app.ActivityThread.main(ActivityThread.java:5299)
04-02 11:12:42.338: E/AndroidRuntime(32166): at java.lang.reflect.Method.invoke(Native Method)
04-02 11:12:42.338: E/AndroidRuntime(32166): at java.lang.reflect.Method.invoke(Method.java:372)
04-02 11:12:42.338: E/AndroidRuntime(32166): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
04-02 11:12:42.338: E/AndroidRuntime(32166): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
04-02 11:12:42.338: E/AndroidRuntime(32166): Caused by: android.view.InflateException: Binary XML file line #18: Error inflating class org.lucasr.twowayview.widget.TwoWayView
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.view.LayoutInflater.createView(LayoutInflater.java:633)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:743)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.view.LayoutInflater.inflate(LayoutInflater.java:482)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
04-02 11:12:42.338: E/AndroidRuntime(32166): at org.lucasr.twowayview.sample.LayoutFragment.onCreateView(LayoutFragment.java:71)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:570)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1220)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.app.Activity.performStart(Activity.java:6036)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2269)
04-02 11:12:42.338: E/AndroidRuntime(32166): ... 10 more
04-02 11:12:42.338: E/AndroidRuntime(32166): Caused by: java.lang.reflect.InvocationTargetException
04-02 11:12:42.338: E/AndroidRuntime(32166): at java.lang.reflect.Constructor.newInstance(Native Method)
04-02 11:12:42.338: E/AndroidRuntime(32166): at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.view.LayoutInflater.createView(LayoutInflater.java:607)
04-02 11:12:42.338: E/AndroidRuntime(32166): ... 23 more
04-02 11:12:42.338: E/AndroidRuntime(32166): Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v4/util/Pools$SimplePool;
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.support.v7.widget.AdapterHelper.<init>(AdapterHelper.java:56)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.support.v7.widget.AdapterHelper.<init>(AdapterHelper.java:71)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.support.v7.widget.RecyclerView.initAdapterManager(RecyclerView.java:410)
04-02 11:12:42.338: E/AndroidRuntime(32166): at android.support.v7.widget.RecyclerView.<init>(RecyclerView.java:294)
04-02 11:12:42.338: E/AndroidRuntime(32166): at org.lucasr.twowayview.widget.TwoWayView.<init>(TwoWayView.java:47)
04-02 11:12:42.338: E/AndroidRuntime(32166): at org.lucasr.twowayview.widget.TwoWayView.<init>(TwoWayView.java:43)
04-02 11:12:42.338: E/AndroidRuntime(32166): ... 26 more
04-02 11:12:42.338: E/AndroidRuntime(32166): Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v4.util.Pools$SimplePool" on path: DexPathList\[\[zip file "/data/app/org.lucasr.twowayview.sample-2/base.apk"\],nativeLibraryDirectories=\[/vendor/lib, /system/lib\]\]
04-02 11:12:42.338: E/AndroidRuntime(32166): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
04-02 11:12:42.338: E/AndroidRuntime(32166): at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
04-02 11:12:42.338: E/AndroidRuntime(32166): at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
04-02 11:12:42.338: E/AndroidRuntime(32166): ... 32 more
04-02 11:12:42.338: E/AndroidRuntime(32166): Suppressed: java.lang.ClassNotFoundException: android.support.v4.util.Pools$SimplePool
04-02 11:12:42.338: E/AndroidRuntime(32166): at java.lang.Class.classForName(Native Method)
04-02 11:12:42.338: E/AndroidRuntime(32166): at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
04-02 11:12:42.338: E/AndroidRuntime(32166): at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
04-02 11:12:42.338: E/AndroidRuntime(32166): at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
04-02 11:12:42.338: E/AndroidRuntime(32166): ... 33 more
04-02 11:12:42.338: E/AndroidRuntime(32166): Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
从错误中其实根本看不出个名堂,不过隐约感觉是在使用RecyclerView的时候出了些问题,而且这个错误反复出现。
Didn't find class "android.support.v4.util.Pools$SimplePool" on path: DexPathList\[\[zip file
于是在stackoverflow上搜这个问题,发现是因为RecyclerView控件所依赖的android-support-v4包版本不一致造成的,即项目本身使用了一个appcompat的依赖(appcompat中包含了android-support-v4.jar),而这个support-v4和RecyclerView依赖的support-v4不是一个版本(从RecyclerView的源码中可以看到其确实使用了不少的support-v4工具类)。
其实这是Eclipse adt 的一个bug ,因为, 但是一般来说,如果是自己手把手创建的项目,兼容包冲突的这种情况下Eclipse会提示类似于如下的文字
[2015-04-02 11:50:27 - RecyclerViewDemo] Found 2 versions of android-support-v4.jar in the dependency list,
[2015-04-02 11:50:27 - RecyclerViewDemo] but not all the versions are identical (check is based on SHA-1 only at this time).
[2015-04-02 11:50:27 - RecyclerViewDemo] All versions of the libraries must be the same at this time.
[2015-04-02 11:50:27 - RecyclerViewDemo] Versions found are:
[2015-04-02 11:50:27 - RecyclerViewDemo] Path: E:\安卓\workspace\RecyclerViewDemo\libs\android-support-v4.jar
[2015-04-02 11:50:27 - RecyclerViewDemo] Length: 995624
[2015-04-02 11:50:27 - RecyclerViewDemo] SHA-1: 3e4e879d0b3dc11f2feb3f55e77e3b5bd82c4a28
[2015-04-02 11:50:27 - RecyclerViewDemo] Path: E:\安卓\项目\appcompat_v7\libs\android-support-v4.jar
[2015-04-02 11:50:27 - RecyclerViewDemo] Length: 627582
[2015-04-02 11:50:27 - RecyclerViewDemo] SHA-1: cb6883d96005bc85b3e868f204507ea5b4fa9bbf
[2015-04-02 11:50:27 - RecyclerViewDemo] Jar mismatch! Fix your dependencies
可是导入的项目却没有提示。搞笑的是能正常编译。我试了两个导入项目都是如此。
防范这种问题发生的手段主要是所有兼容包都是用同一个版本的,即都使用sdk\extras\android\support包下面的一套东西。