누군가 Android에서 새로운 Java 7 언어 기능을 사용해 보았는지 궁금하십니까? 안드로이드가 자바가 내뿜는 바이트 코드를 읽고 그것을 dex로 바꾼다는 것을 알고 있습니다. 그래서 내 질문은 Java 7의 바이트 코드를 이해할 수 있습니까?
누군가 Android에서 새로운 Java 7 언어 기능을 사용해 보았는지 궁금하십니까? 안드로이드가 자바가 내뿜는 바이트 코드를 읽고 그것을 dex로 바꾼다는 것을 알고 있습니다. 그래서 내 질문은 Java 7의 바이트 코드를 이해할 수 있습니까?
답변:
Android Studio를 사용하는 경우 패치없이 Java 7 언어 가 자동으로 활성화되어야합니다. Try-with-resource에는 API 레벨 19 이상이 필요하며 NIO 2.0 항목이 없습니다.
Java 7 기능을 사용할 수 없으면 을 편집하는 방법에 대한 @Nuno 의 답변을 참조 하십시오 build.gradle
.
다음은 역사적 관심사를위한 것입니다.
Java 7의 작은 부분은 확실히 Android와 함께 사용할 수 있습니다 (참고 : 4.1에서만 테스트했습니다).
우선, Java 컴파일러 1.5 및 1.6 만 호환되도록 하드 코딩 되어 있기 때문에 Eclipse의 ADT를 사용할 수 없습니다 . ADT를 다시 컴파일 할 수는 있지만 전체 Android를 함께 다시 컴파일하는 것 외에는 간단한 방법이 없습니다.
그러나 Eclipse를 사용할 필요는 없습니다. 예를 들어 Android Studio 0.3.2 , IntelliJ IDEA CE 및 기타 javac 기반 IDE는 Android 로의 컴파일을 지원 하며 다음을 사용하여 최대 Java 8까지 준수를 설정할 수 있습니다.
이 기능 은 Java 7 언어 기능 만 허용 하며 , 절반의 향상도 라이브러리에서 제공되므로 어떠한 이점도 얻을 수 없습니다. 사용할 수있는 기능은 라이브러리에 의존하지 않는 기능입니다.
<>
)catch (Exc1 | Exc2 e)
)1_234_567
)0b1110111
)그리고이 기능들은 아직 사용할 수 없습니다 :
try
가진 - - 자원 문 -가 존재하지 않는 인터페이스 "java.lang.AutoCloseable"를 필요로하기 때문에 (이 4.4에서 공개적으로 사용할 수 있습니다)... "yet":) 안드로이드의 라이브러리가 1.6을 대상으로하지만 안드로이드 소스에는 AutoCloseable 과 같은 인터페이스가 포함되어 있으며 Closeable 과 같은 기존 인터페이스 는 AutoCloseable에서 상속됩니다 (SafeVarargs는 실제로 누락되었습니다). 우리는 성찰을 통해 그 존재를 확인할 수있었습니다. Javadoc에 @hide
태그가있어 "android.jar"에 포함되지 않기 때문에 단순히 숨겨져 있습니다.
이미 존재하는 문제 등이 내가 숨겨진 내부 API를 사용할 수와 안드로이드 SDK를 구축하려면 어떻게합니까? 그 방법을 다시 얻는 방법에 대해. 당신은 단지 필요 교체 기존의 "android.jar"사용자 정의 하나, 자바 (7) API를 한 후 많은 사람들이 사용할 수있게됩니다 우리와 현재 플랫폼의 참조 (절차가 Eclipse에서 유사하다. 프로젝트 구조 → SDK를 확인하십시오.)
AutoCloseable 외에도 다음과 같은 Java 7 라이브러리 기능 도 공개됩니다.
그게 전부입니다. 특히 NIO 2.0은 존재하지 않으며 Arrays.asList는 여전히 @SafeVarargs가 아닙니다.
nio2
하며 다른 좋은 점은 분명히 좋은 소식이 될 것입니다.
AutoCloseable
ICS (또는 HoneyComb)까지는 Android 런타임에 인터페이스가 존재하지 않는다는 점을 언급 할 가치가 있습니다. 따라서 패치 된 android.jar을 사용하더라도 NoClassDefFoundError
2.x 시스템에서 받게 됩니다.
invokedynamic
Java 6을 대상으로하는 JVM에서 지원하지 않기 때문에 Dalvik VM을 수정해야합니다 .
편집 : 이것이 작성된 시점에서 최신 릴리스는 Android 9 및 Eclipse Indigo였습니다. 그때부터 상황이 바뀌 었습니다.
예, 시도했습니다. 그러나 호환성이 실제로 Java 7을 사용하는 방법 (최소한 방법은 아님)으로 레벨 6으로 제한되었으므로 이것은 훌륭한 테스트가 아닙니다.
그런 다음 최신 버전의 Android SDK를 설치했습니다 (이 게시물 작성 당시 편집 : Honeycomb, API13). JDK 7을 찾아서 올바르게 설치했습니다. ADT도 마찬가지입니다.
그러나 Hello Word Android 앱을 컴파일하고 실행하려고 할 때 놀랐습니다. 호환성은 Java 6으로 강제 설정할 수없는 Java 6으로 설정되었습니다.
내가 가진 그래서 안녕하세요을 작업하고, 다른 응용 프로그램은 더 복잡하고 사용 SQLite
, Listview
, Sensor
과 Camera
, 그러나 이것은 단지 자바 7의 처리 호환성이 잘 안드로이드로 작동하는 것 같군 것을 증명한다.
그래서 누군가 위에 보이는 Eclipse 제한을 우회하기 위해 좋은 오래된 Ant를 사용해 보았습니까?
어쨌든 SDK는 여기 설명 된대로 Java 5 또는 6과 함께 사용하도록 설계되었습니다 .
Java 7에서 작동하는 것이있을 수 있지만 "우연히"작동합니다. DEX 구축이 제대로 작동하지 않을 수 있으며 DEX가 구축되면 작동 할 수도 있습니다. 이는 규정되지 않은 JDK를 사용하면 정의에 의해 예측할 수없는 결과를 제공하기 때문입니다.
누군가 일반 Java 7에서 Android 앱을 성공적으로 구축 했더라도 JDK를 사용할 수 없습니다. 다른 애플리케이션에 적용된 동일한 프로세스가 실패하거나 결과 애플리케이션에 해당 JDK 사용과 관련된 버그가있을 수 있습니다. 권장하지 않습니다.
webapps 개발에 관여하는 사람들에게는 Java 4 또는 Java 6 용으로 작성된 웹 응용 프로그램을 Java 4 전용 응용 프로그램 서버 (예 : Weblogic 8)로 배포하는 것과 동일합니다. 이것은 효과가있을 수 있지만 시도하는 것 이외의 다른 목적으로 권장 할 수있는 것은 아닙니다.
dalvikvm.com에서 인용 :
Android SDK에 포함 된 dx는 일반 Java 컴파일러에서 컴파일 한 Java 클래스의 Java 클래스 파일을 다른 클래스 파일 형식 (.dex 형식)으로 변환합니다.
즉, .java 소스 파일은 중요하지 않으며 .class 바이트 코드 일뿐입니다.
내가 아는 한 invokedynamic 만 Java 7의 JVM 바이트 코드에 추가되었으며 나머지는 Java 6과 호환됩니다. Java 언어 자체는 invokedynamic을 사용하지 않습니다 . String을 사용 하는 switch 문 또는 멀티 캐치 와 같은 다른 새로운 기능 은 단지 신택 틱 설탕이며 바이트 코드 변경이 필요하지 않습니다. 예를 들어, 멀티 캐치 는 각 가능한 예외에 대한 캐치 블록을 복사합니다 .
유일한 문제는 Java 7에 도입 된 새로운 클래스가 AutoCloseable 과 같은 Android에서 누락 되었기 때문에 try -with-resources 기능을 사용할 수 있는지 확실하지 않습니다 (누군가 시도 했습니까?).
그것에 대한 의견이 있으십니까? 뭔가 빠졌습니까?
@KennyTM의 위의 답변을 확장하려면 4.0.3 이상 ( minSdkVersion = 15 )을 대상으로하는 경우 대상의 SDK android.jar에 몇 개의 클래스를 추가하여 숨겨진 API를 사용할 수 있습니다.
이 작업을 마치면 모든 Closeable에서 try-with-resources를 사용하고 자체 클래스에서 AutoCloseable을 구현할 수 있습니다.
이 API를 사용 가능하게하기 위해 android.jar에서 수정해야하는 모든 클래스의 소스 및 바이너리가 포함 된 Zip을 만들었습니다. 압축을 풀고 바이너리를
android-sdk / platforms / android-NN / android.jar에 추가하면됩니다 .
여기에서 다운로드 할 수 있습니다 : http://db.tt/kLxAYWbr
또한 노트의 인 달의 지난 몇 년, 엘리엇 휴즈는 안드로이드 나무에 몇 커밋을했다 : AutoCloseable 마무리 , 추가 SafeVarargs , 숨김 다양한 API , 고정의 Throwable의 보호 생성자 와 DX의 버전 (51) 클래스 파일에 대한 추가 지원 . 그래서 마침내 몇 가지 진전이 있습니다.
편집 (2014 년 4 월) :
SDK 19 릴리스에서는 더 이상 추가 API로 android.jar를 패치 할 필요가 없습니다.
4.0.3 이상 ( minSdkVersion = 15 ) 을 대상으로하는 앱에 대해 Android Studio에서 try-with-resources를 사용하는 가장 좋은 방법 은 다음 compileOptions
을 추가하는 것입니다 build.gradle
.
android {
compileSdkVersion 19
buildToolsVersion '19.0.3'
defaultConfig {
minSdkVersion 15
targetSdkVersion 19
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
Android Studio는이 API 수준에서 리소스를 사용하여 리소스를 사용할 수 없다고 불평하지만 내 경험에 따르면 가능합니다. 이 프로젝트는 4.0.3 이상의 장치에서 문제없이 빌드되고 실행됩니다. 500k + 기기에 설치된 앱과 관련하여 아무런 문제가 없었습니다.
이 경고를 무시하려면 다음을 추가하십시오 lint.xml
.
<issue id="NewApi">
<ignore regexp="Try-with-resources requires API level 19"/>
</issue>
이것이 순수한 개미와 함께 작동하게하는 것은 약간의 문제입니다.
그러나 그것은 나를 위해 일했다 : http://www.informit.com/articles/article.aspx?p=1966024
custom_rules.xml
여기에서 내 대답을 참조하십시오 : stackoverflow.com/a/24608415/194894
어떤 사람들은 내가 찾은이 자식 프로젝트에 관심이있을 수 있습니다. 안드로이드에서 Java 7을 실행할 수있는 것 같습니다. https://github.com/yareally/Java7-on-Android
그러나 현재 작업중 인 프로젝트에 이것을 추가하면 너무 위험합니다. Google이 공식적으로 Java 7을 지원할 때까지 기다립니다.