使用RecyclerView时遇到的问题

总体来说,讲的不是很清楚,还请大家见谅。


最近两天在Linux中的Android项目开发上遇到这个问题。
是因为之前的一个平台(android 5.0) 的App 在 另一个平台(android6.0)上也同时需要。


1.将原来app的源码 copy 到新建的仓库   
2.排除一些平台彼此不兼容的属性,OK,mm -B -> complie succeeded。


然后就遇到了难了我一天一夜的难题。


出现了下面的这个issue:


--------- beginning of main
--------- beginning of system
01-20 11:20:27.632 26248 26248 D AndroidRuntime: Shutting down VM
--------- beginning of crash
01-20 11:20:27.634 26248 26248 E AndroidRuntime: FATAL EXCEPTION: main
01-20 11:20:27.634 26248 26248 E AndroidRuntime: Process: com.android.calculator2, PID: 26248
01-20 11:20:27.634 26248 26248 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.calculator2/com.android.calculator2.Calculator}: android.view.InflateException: Binary XML file line #22: Binary XML file line #39: Error inflating class android.support.v7.widget.RecyclerView
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2452)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.app.ActivityThread.access$900(ActivityThread.java:158)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1364)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.os.Looper.loop(Looper.java:148)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5515)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: Caused by: android.view.InflateException: Binary XML file line #22: Binary XML file line #39: Error inflating class android.support.v7.widget.RecyclerView
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at com.android.internal.policy.PhoneWindow.setContentView(PhoneWindow.java:393)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.app.Activity.setContentView(Activity.java:2276)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at com.android.calculator2.Calculator.onCreate(Calculator.java:156)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:6445)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2405)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: ... 9 more
01-20 11:20:27.634 26248 26248 E AndroidRuntime: Caused by: android.view.InflateException: Binary XML file line #39: Error inflating class android.support.v7.widget.RecyclerView
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.createView(LayoutInflater.java:645)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:764)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.rInflate(LayoutInflater.java:835)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.rInflate(LayoutInflater.java:838)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.rInflate(LayoutInflater.java:838)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.parseInclude(LayoutInflater.java:971)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.rInflate(LayoutInflater.java:831)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: ... 17 more
01-20 11:20:27.634 26248 26248 E AndroidRuntime: Caused by: java.lang.reflect.InvocationTargetException
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at java.lang.reflect.Constructor.newInstance(Native Method)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.view.LayoutInflater.createView(LayoutInflater.java:619)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: ... 29 more
01-20 11:20:27.634 26248 26248 E AndroidRuntime: Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/recyclerview/R$styleable;
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.support.v7.widget.RecyclerView.<init>(RecyclerView.java:440)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at android.support.v7.widget.RecyclerView.<init>(RecyclerView.java:409)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: ... 31 more
01-20 11:20:27.634 26248 26248 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v7.recyclerview.R$styleable" on path: DexPathList[[zip file "/system/app/ExactCalculator/Calculator.apk"],nativeLibraryDirectories=[/system/app/ExactCalculator/lib/arm64, /vendor/lib64, /system/lib64]]
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: ... 33 more
01-20 11:20:27.634 26248 26248 E AndroidRuntime: Suppressed: java.lang.ClassNotFoundException: android.support.v7.recyclerview.R$styleable
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at java.lang.Class.classForName(Native Method)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
01-20 11:20:27.634 26248 26248 E AndroidRuntime: at java.lang.BootClassLoader.loadClass(ClassLoader.java:8




从log中我们可以看到,

1.Binary XML file line #22: Binary XML file line #39: Error inflating class android.support.v7.widget.RecyclerView


2.同时还有这样的 java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/recyclerview/R$styleable 


3.Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v7.recyclerview.R$styleable"

一开始只注意到了第一点,于是在网络上查呀查:
就发现大家的说法就是 在eclipse或者android studio上 因为sdk的版本不match,等等的。有的人说把android.support.v7.recyclerview.jar这个包换掉,换成match的版本的就好了,但我这边因为开发方式不一样,就又断掉了。但是却让我知道了是版本的问题


后来
有的人说是
1.AndroidManifest.xml中的targetSDKVersion不对,fix -> NOK。
2.build.gradle中的某些属性不对。fix -> NOK

因为App是独立的apk,就去这5.0,6.0 andorid 的源码中去找android.support.v7.recyclerview.


同时又注意到了这两点错误
2.同时还有这样的 java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v7/recyclerview/R$styleable 

3.Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v7.recyclerview.R$styleable"


从Log中我们可以看到
at android.support.v7.widget.RecyclerView.<init>(RecyclerView.java:440)
at android.support.v7.widget.RecyclerView.<init>(RecyclerView.java:409)
RecyclerView的409 和 440 行出错


就发现了在 frameworks/support/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java中

使用到了R.styleable.RecyclerView这个属性,而第2,3点log中出现的就是R$styleable 的错误。

明确了:在android6.0版本RecyclerView类中用到了R.styleable.RecyclerView这个资源。而android5.0的版本中的RecyclerView类没用到R.styleable.RecyclerView

回到frameworks/support/v7/recyclerview/目录下就会发现
-----------5.0 没有res/ 文件夹
-----------6.0 则有



那么现在中场总结一下,因为andorid5.0中的RexyclerView类中没有使用res资源,而6.0却使用了。同时6.0的res/资源是存在的。只能说明,我们没有引用到,或者说是没有把对应的资源加载,进行编译。

-------------------------------------------------------------------------------------------------------

问题又来了:res/资源是在哪里加载的?  

----------》 Android.mk 文件下有这么一段


          LOCAL_STATIC_JAVA_LIBARIES := android-support-v7-recyclerview
              .......
              .......
              .......


          LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/ ,$(res_dir)) 
              .......
              .......
              .......
          LOCAL_APPT_FLAGS := --auto-add-overlay\
              .......

发现了android-support-v7-recyclerview的身影


那这内容是什么意思?

1.LOCAL_STATIC_JAVA_LIBARIES 本地静态java库。
2.LOCAL_RESOURCE_DIR 本地资源文件,默认是product package和device package下面相应的res路径和$(LOCAL_PATH)/res
3.LOCAL_AAPT_FLAGS += -c ldpi -c mdpi  
  上面指定了编译时打包 ldpi 和mdpi 如果系统默认的是hdpi的话,那就是这三种都会装入包中


在中场总结的时候,已经明确,是因为res资源没有加载。
所以只需要在LOCAL_RESOURCE_DIR中加上frameworks/support/v7/recyclerview/res就可以了

Android.mk文件内容变成:


          LOCAL_STATIC_JAVA_LIBARIES := android-support-v7-recyclerview
              .......
              .......
              .......


          LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/ ,$(res_dir)) 
              frameworks/support/v7/recyclerview/res \
              .......
              .......
              .......
          LOCAL_APPT_FLAGS := --auto-add-overlay\
              --extra-package android.support.v7.recyclerview \
              .......


再次编译,正常运行。


======================================================================================================
其实就是因为android的版本升级,RecyclerView 中的创建LayoutManager的方式发生了改变,旧版本里少了个  R.styleable.RecyclerView, 而在新环境下又没将其编译进去,故有此错。


 各位少侠也可以在 package 中的res/attrs.xml 下面自己定义一个`````


总体来说将的不是很清楚, 还请大家见谅 。。   





















猜你喜欢

转载自blog.csdn.net/dfghhvbafbga/article/details/50550560
今日推荐