我向现有的正在运行的项目添加了一些功能,然后我测试了应用程序的完整测试,发现任何 RecyclerView 在添加/删除项目后崩溃(在通知适配器更改后)。
我正在使用 notifyDataSetChanged()
并尝试使用 notifyItemRemoved()
和 notifyItemInserted()
但问题仍然存在。
我的 gradle 文件:
android {
compileSdkVersion 23
buildToolsVersion '23.0.3'
defaultConfig {
minSdkVersion 16
targetSdkVersion 22
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.2.0'
compile 'com.android.support:cardview-v7:23.2.0'
compile 'com.android.support:recyclerview-v7:23.2.0'
compile 'com.android.support:design:23.2.0'
.......
.......
日志:
08-29 09:48:21.874: W/dalvikvm(4290): threadid=1: thread exiting with uncaught exception (group=0xb2d29b20)
08-29 09:48:21.874: W/System.err(4290): java.lang.AbstractMethodError: abstract method not implemented
08-29 09:48:21.884: W/System.err(4290): at android.support.v7.widget.RecyclerView$ItemAnimator.animateDisappearance(RecyclerView.java)
08-29 09:48:21.884: W/System.err(4290): at android.support.v7.widget.RecyclerView.animateDisappearance(RecyclerView.java:3252)
08-29 09:48:21.884: W/System.err(4290): at android.support.v7.widget.RecyclerView.access$700(RecyclerView.java:147)
08-29 09:48:21.884: W/System.err(4290): at android.support.v7.widget.RecyclerView$4.processDisappeared(RecyclerView.java:431)
08-29 09:48:21.884: W/System.err(4290): at android.support.v7.widget.ViewInfoStore.process(ViewInfoStore.java:246)
08-29 09:48:21.884: W/System.err(4290): at android.support.v7.widget.RecyclerView.dispatchLayoutStep3(RecyclerView.java:3098)
08-29 09:48:21.884: W/System.err(4290): at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2917)
08-29 09:48:21.884: W/System.err(4290): at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3283)
08-29 09:48:21.884: W/System.err(4290): at android.view.View.layout(View.java:14817)
08-29 09:48:21.884: W/System.err(4290): at android.view.ViewGroup.layout(ViewGroup.java:4631)
08-29 09:48:21.884: W/System.err(4290): at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1055)
08-29 09:48:21.884: W/System.err(4290): at android.view.View.layout(View.java:14817)
08-29 09:48:21.884: W/System.err(4290): at android.view.ViewGroup.layout(ViewGroup.java:4631)
08-29 09:48:21.884: W/System.err(4290): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
08-29 09:48:21.884: W/System.err(4290): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
08-29 09:48:21.884: W/System.err(4290): at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
08-29 09:48:21.884: W/System.err(4290): at android.view.View.layout(View.java:14817)
08-29 09:48:21.884: W/System.err(4290): at android.view.ViewGroup.layout(ViewGroup.java:4631)
08-29 09:48:21.884: W/System.err(4290): at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:122)
08-29 09:48:21.884: W/System.err(4290): at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
08-29 09:48:21.884: W/System.err(4290): at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1170)
08-29 09:48:21.894: W/System.err(4290): at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:814)
08-29 09:48:21.894: W/System.err(4290): at android.view.View.layout(View.java:14817)
08-29 09:48:21.894: W/System.err(4290): at android.view.ViewGroup.layout(ViewGroup.java:4631)
08-29 09:48:21.894: W/System.err(4290): at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1191)
08-29 09:48:21.894: W/System.err(4290): at android.view.View.layout(View.java:14817)
08-29 09:48:21.894: W/System.err(4290): at android.view.ViewGroup.layout(ViewGroup.java:4631)
08-29 09:48:21.894: W/System.err(4290): at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
08-29 09:48:21.894: W/System.err(4290): at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
08-29 09:48:21.894: W/System.err(4290): at android.view.View.layout(View.java:14817)
08-29 09:48:21.894: W/System.err(4290): at android.view.ViewGroup.layout(ViewGroup.java:4631)
08-29 09:48:21.894: W/System.err(4290): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
08-29 09:48:21.894: W/System.err(4290): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
08-29 09:48:21.894: W/System.err(4290): at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
08-29 09:48:21.894: W/System.err(4290): at android.view.View.layout(View.java:14817)
08-29 09:48:21.894: W/System.err(4290): at android.view.ViewGroup.layout(ViewGroup.java:4631)
08-29 09:48:21.894: W/System.err(4290): at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
08-29 09:48:21.894: W/System.err(4290): at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
08-29 09:48:21.904: W/System.err(4290): at android.view.View.layout(View.java:14817)
08-29 09:48:21.904: W/System.err(4290): at android.view.ViewGroup.layout(ViewGroup.java:4631)
08-29 09:48:21.904: W/System.err(4290): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
08-29 09:48:21.904: W/System.err(4290): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
08-29 09:48:21.904: W/System.err(4290): at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
08-29 09:48:21.904: W/System.err(4290): at android.view.View.layout(View.java:14817)
08-29 09:48:21.904: W/System.err(4290): at android.view.ViewGroup.layout(ViewGroup.java:4631)
08-29 09:48:21.904: W/System.err(4290): at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
08-29 09:48:21.904: W/System.err(4290): at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
08-29 09:48:21.904: W/System.err(4290): at android.view.View.layout(View.java:14817)
08-29 09:48:21.904: W/System.err(4290): at android.view.ViewGroup.layout(ViewGroup.java:4631)
08-29 09:48:21.904: W/System.err(4290): at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1987)
08-29 09:48:21.904: W/System.err(4290): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1744)
08-29 09:48:21.904: W/System.err(4290): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
08-29 09:48:21.904: W/System.err(4290): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
08-29 09:48:21.904: W/System.err(4290): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
08-29 09:48:21.904: W/System.err(4290): at android.view.Choreographer.doCallbacks(Choreographer.java:574)
08-29 09:48:21.904: W/System.err(4290): at android.view.Choreographer.doFrame(Choreographer.java:544)
08-29 09:48:21.904: W/System.err(4290): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
08-29 09:48:21.904: W/System.err(4290): at android.os.Handler.handleCallback(Handler.java:733)
08-29 09:48:21.904: W/System.err(4290): at android.os.Handler.dispatchMessage(Handler.java:95)
08-29 09:48:21.904: W/System.err(4290): at android.os.Looper.loop(Looper.java:136)
08-29 09:48:21.904: W/System.err(4290): at android.app.ActivityThread.main(ActivityThread.java:5017)
08-29 09:48:21.904: W/System.err(4290): at java.lang.reflect.Method.invokeNative(Native Method)
08-29 09:48:21.904: W/System.err(4290): at java.lang.reflect.Method.invoke(Method.java:515)
08-29 09:48:21.904: W/System.err(4290): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
08-29 09:48:21.904: W/System.err(4290): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
08-29 09:48:21.904: W/System.err(4290): at dalvik.system.NativeStart.main(Native Method)
最佳答案
AbstractMethodError
是双重异常(既有在编译时被捕获的情况,也有在运行时被捕获的情况)。此类的 Java 文档指出“当应用程序尝试调用抽象方法时抛出。”。
抽象方法是没有实现的功能,即它们只有定义的函数签名(也称为 header )。所以当 JVM 跳转到一个抽象方法的入口点时,它会抛出这个异常,因为它不知道该做什么(函数定义仍然是空的)。因此,您需要使用具有实现的实际函数来覆盖您正在扩展的类中定义的所有抽象函数。特别是在您的情况下,RecyclerView
调用抽象函数 animateDissapearance从其适配器集合中删除项目时,它还会调用抽象函数 animateAppearance将项目添加到其适配器的集合中时。您似乎没有在 RecyclerView 类中覆盖这些功能。
对您的异常的修复以上一段结束。这只是为了以防万一你想知道为什么有人会在他们什么都不做甚至导致异常时使用抽象方法。
抽象方法(主要用于库和其他开发人员工具)允许开发人员引用、安排和处理任意复杂的工作单元,而无需担心其实际实现。这在您开发库时特别有用,因为您不知道用户将要使用的案例。我将举一个例子,希望人们可以很容易地认同:
假设您正在开发一种工具,希望支持独立开发人员开发的插件。举一个更清楚的例子——让它成为一个电子邮件客户端。现在,我们来看看您的电子邮件客户端应该发送电子邮件的一种情况。并假设您希望开发社区开发插件,在发送之前将电子邮件副本备份到硬盘、云存储或与邮件相关的任何其他操作。你不知道也不能知道他们在做什么,但你知道他们需要什么作为输入并期望输出什么。所以你像这样实现你的邮件发送功能:
boolean sendMail(HashMap<String, String> headers, String body, String recipient, List<DeveloperPlugin> activePlugins) {
//Your parameter validation
for(DeveloperPlugin plugin : activePlugins) {
plugin.runBeforeSendEmailAction(headers, body);
}
//Send email
}
然后您指示您的开发人员社区将他们所有的逻辑存储在一个扩展 DeveloperPlugin
的类中类(或实现 DeveloperPlugin
接口(interface))并在 runBeforeSendEmailAction(HashMap<String, String> headers, String body)
内部具体实现他们想要在实际发送邮件之前执行的所有与邮件相关的操作该类(接口(interface))的功能。这解决了作为主要模块开发人员面临的最大问题——无论插件开发人员实现什么,如何确保应用程序的行为相同。它还解决了插件开发人员面临的最大问题 - 我如何知道我的函数将获得什么输入以及我如何以及何时调用它?
我在这方面做得太过分了,但希望有人会觉得它很有趣,甚至可能有帮助。
干杯! :D
关于android - RecyclerView Adapter 中未实现抽象方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39215334/