Android上Scala中的自定义集合 - TraversableFactory与NoClassDefFoundError崩溃

时间:2013-05-16 12:52:06

标签: android scala noclassdeffounderror scala-collections

我正在尝试实现自定义集合,因此我正在关注this post

现在,导致崩溃的'裸'代码是:

object TraversableCollection extends TraversableFactory[TraversableCollection] {
    implicit def canBuildFrom[T] : CanBuildFrom[Coll, T, TraversableCollection[T]] = new GenericCanBuildFrom[T]

    def newBuilder[T] = new ListBuffer[T].mapResult(x => new TraversableCollection(x:_*))
}

class TraversableCollection[T](seq : T*) extends Traversable[T]
                                         with GenericTraversableTemplate[T, TraversableCollection]
                                         with TraversableLike[T, TraversableCollection[T]] {
    override def companion = TraversableCollection  
    def foreach[U](f: T => U) = seq.foreach(f)
}

我的整个实现并不复杂,它只是一个包含不可变Vector的集合,它可以在项目上前后移动,在内部存储索引值并暴露“当前”项。基本上 - 一个双向迭代器。

无论如何,整个实现(上面的骨架和我的完整实现)在REPL中运行得很好(这是一个完整的实现):

scala> val vec = Vector("Just", "testing", "it")
vec: scala.collection.immutable.Vector[String] = Vector(Just, testing, it)

scala> val t = new TraversableCollection(vec:_*)
t: TraversableCollection[String] = (Just, testing, it)

scala> t.current
res6: String = Just

scala> t.moveForward(2)

scala> t.current
res8: String = it

scala> t.moveBack(1)

scala> t.current
res10: String = testing

简单,我需要它。这是问题所在:在Android应用程序中,当我到达创建集合时,PathClassLoader开始崩溃,然后转到:

this: NoClassDefFoundError 
detailMessage: "scala.collection.generic.TraversableFactory"

并在日志中死掉:

05-16 12:14:35.056: E/AndroidRuntime(575): java.lang.VerifyError: my.package.data.TraversableCollection

为什么呢?我有什么可以做的吗?

现在,我的临时解决方案是删除GenericTraversableTemplateTraversableLike,并保留Traversable特征。不完美,但现在会很好。

设定:

  • 来自ADT的Eclipse,Scala IDE插件+ AndroidProguardScala插件

  • Scala 2.10.0-2012-12-05

[编辑] Proguard相关

根据我对Proguard的非常非常有限的了解,它似乎应该被禁用,因为路径在project.properties注释掉了:

# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

我尝试评论并取消注释该行,并将其添加到proguard-project.txt:

-keepnames scala.collection.generic.TraversableFactory

无论如何,我仍然有同样的错误。

[编辑2]仍与Proguard相关

以下是AndroidProguardScala生成的默认配置(以及应用程序崩溃时使用的配置):

-injars "F:\adt-bundle-windows-x86_64\eclipse\configuration\org.eclipse.osgi\bundles\373\1\.cp\lib\scala-library.jar"(!META-INF/MANIFEST.MF)
-injars "F:\adt-bundle-windows-x86_64\eclipse\configuration\org.eclipse.osgi\bundles\373\1\.cp\lib\scala-actors.jar"(!META-INF/MANIFEST.MF)
-injars "F:\adt-bundle-windows-x86_64\eclipse\configuration\org.eclipse.osgi\bundles\372\1\.cp\lib\scala-reflect.jar"(!META-INF/MANIFEST.MF)

-outjars "F:\Projects\AndroidScalaProject\proguard_cache\jartender_cache_7212076580182750151.jar"
-injars "F:\Projects\AndroidScalaProject\bin\classes"
-libraryjars "F:\adt-bundle-windows-x86_64\sdk\platforms\android-17\android.jar"
-libraryjars "F:\Projects\AndroidScalaProject\libs\android-support-v4.jar"

-keep public class * extends android.**
-dontwarn **$$anonfun$*
-dontwarn
-dontoptimize
-dontobfuscate
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers

-ignorewarnings
-forceprocessing

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
                SourceFile,LineNumberTable,*Annotation*,EnclosingMethod

-keep public class scala.ScalaObject { *; }
-keep public class scala.Function0, scala.Function1

# Fix for https://issues.scala-lang.org/browse/SI-5397 

-keep class scala.collection.SeqLike {
    public protected *;
}

# AndroidProguardScala version: 0.0.47.201302150529

-keep class ...
-keep class ... # and a looot of that for anon-functions and classes in the project.
# Here's one that's interesting:
-keep class my.project.data.TraversableCollection {*;}

0 个答案:

没有答案