2014-11-20 6 views
0

내가 안드로이드 그루비에 대한 몇 가지 코드를 작성하려하고 내가 객체에 동적으로 속성을 추가 metaclass를 사용할 수 없다는 사실을 우연히 발견 :안드로이드 그루비 메타 클래스

java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/invoke/MethodHandles; 
     at org.codehaus.groovy.vmplugin.v7.IndyInterface.<clinit>(IndyInterface.java:81) 
     at org.codehaus.groovy.vmplugin.v7.Java7.invalidateCallSites(Java7.java:31) 
     at org.codehaus.groovy.reflection.ClassInfo.incVersion(ClassInfo.java:87) 
     at groovy.lang.MetaClassImpl.incVersion(MetaClassImpl.java:3445) 
     at groovy.lang.ExpandoMetaClass.performRegistryCallbacks(ExpandoMetaClass.java:931) 
     at groovy.lang.ExpandoMetaClass.access$400(ExpandoMetaClass.java:254) 
     at groovy.lang.ExpandoMetaClass$2.call(ExpandoMetaClass.java:860) 
     at groovy.lang.ExpandoMetaClass.performOperationOnMetaClass(ExpandoMetaClass.java:813) 
     at groovy.lang.ExpandoMetaClass.registerBeanProperty(ExpandoMetaClass.java:842) 
     at groovy.lang.ExpandoMetaClass.setProperty(ExpandoMetaClass.java:791) 
     at org.codehaus.groovy.runtime.HandleMetaClass.setProperty(HandleMetaClass.java:91) 
     at org.codehaus.groovy.runtime.InvokerHelper.setProperty(InvokerHelper.java:191) 
     at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.setProperty(ScriptBytecodeAdapter.java:480) 

it.mapMarker.metaClass.project = it 

실패

그 이유는 클래스 MethodHandle이 JDK 1.7에서만 추가되었다고 생각합니다.

내가 이것을 극복 할 수있는 방법을 생각해보십시오. 분명히 클래스를 확장하여 원하는 필드를 줄 수는 있지만, 아마도 Groovy의 요점이 누락되었을 것입니다.

답변

3

우선 Android에서 런타임 메타 프로그래밍을 사용하는 것은 좋지 않습니다. 재미 있지는 않지만 @CompileStatic을 사용하는 것보다 훨씬 느립니다 (Android에서는 리플렉션을 활용할 수 없으므로 리플렉션을 사용함). 언어의 정적 기능에만 의존하는 것이 더 좋습니다. JSonSlurper와 같은 동적 기능은 사례별로 제공됩니다.

보고있는 오류는 Groovy 2.4.0-beta-4에서 수정 될 것입니다. 그러나 어쨌든이 작업을 권장하지는 않습니다. 대신 정적 컴파일과 호환되는 이점을 갖는 확장 모듈을 사용하는 것이 좋습니다. 기존 강의도 향상시킬 수 있습니다.

예를 들어 SpeakerTime 데모에 사용한 코드를 참조하십시오. extensions이라는 모듈이 Context 클래스에 확장 메소드를 제공합니다. 나는 그것이가는 길이다라고 생각한다.

1

항상 Android와 완벽하게 호환되는 SnapScript과 같은 언어를 사용할 수 있습니다. Groovy의 모든 기능을 갖추고 있으며 원격 디버깅을 더 잘 지원합니다.