누군가 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까지 준수를 설정할 수 있습니다.
- 파일 → 프로젝트 구조 → 모듈 → (두 번째 창에서 모듈 선택) → 언어 수준 → ( “7.0-다이아몬드, ARM, 멀티 캐치 등”선택)
이 기능 은 Java 7 언어 기능 만 허용 하며 , 절반의 향상도 라이브러리에서 제공되므로 어떠한 이점도 얻을 수 없습니다. 사용할 수있는 기능은 라이브러리에 의존하지 않는 기능입니다.
- 다이아몬드 연산자 (
<>
) - 스트링 스위치
- 다중 캐치 (
catch (Exc1 | Exc2 e)
) - 숫자 리터럴의 밑줄 (
1_234_567
) - 이진 리터럴 (
0b1110111
)
그리고이 기능들은 아직 사용할 수 없습니다 :
try
가진 – – 자원 문 -가 존재하지 않는 인터페이스 “java.lang.AutoCloseable”를 필요로하기 때문에 (이 4.4에서 공개적으로 사용할 수 있습니다)- @SafeVarargs 주석- “java.lang.SafeVarargs”가 없기 때문에
… “yet”:) 안드로이드의 라이브러리가 1.6을 대상으로하지만 안드로이드 소스에는 AutoCloseable 과 같은 인터페이스가 포함되어 있으며 Closeable 과 같은 기존 인터페이스 는 AutoCloseable에서 상속됩니다 (SafeVarargs는 실제로 누락되었습니다). 우리는 성찰을 통해 그 존재를 확인할 수있었습니다. Javadoc에 @hide
태그가있어 “android.jar”에 포함되지 않기 때문에 단순히 숨겨져 있습니다.
이미 존재하는 문제 등이 내가 숨겨진 내부 API를 사용할 수와 안드로이드 SDK를 구축하려면 어떻게합니까? 그 방법을 다시 얻는 방법에 대해. 당신은 단지 필요 교체 기존의 “android.jar”사용자 정의 하나, 자바 (7) API를 한 후 많은 사람들이 사용할 수있게됩니다 우리와 현재 플랫폼의 참조 (절차가 Eclipse에서 유사하다. 프로젝트 구조 → SDK를 확인하십시오.)
AutoCloseable 외에도 다음과 같은 Java 7 라이브러리 기능 도 공개됩니다.
- ConcurrentModificationException, LinkageError 및 AssertionError의 예외 체인 생성자
- 프리미티브의 정적 .compare () 메소드 : Boolean.compare (), Byte.compare (), Short.compare (), Character.compare (), Integer.compare (), Long.compare ().
- 환율 : .getAvailableCurrencies (), .getDisplayName () (그러나 없이 .getNumericCode ())
- BitSet : .previousSetBit (), .previousClearBit (), .valueOf (), .toLongArray (), .toByteArray ()
- 컬렉션 : .emptyEnumeration (), .emptyIterator (), .emptyListIterator ()
- 자동 닫기
- Throwable : .addSuppressed (), .getSuppressed () 및 4 인수 생성자
- 문자 : .compare (), .isSurrogate () .getName (), .highSurrogate (), .lowSurrogate (), .isBmpCodePoint () (그러나 없이 .isAlphabetic ()와 .isIdeographic ())
- 시스템 : .lineSeparator () (언급되지 않았습니까?)
- java.lang.reflect.Modifier : .classModifiers (), .constructorModifiers (), .fieldModifiers (), .interfaceModifiers (), .methodModifiers ()
- NetworkInterface : .getIndex (), .getByIndex ()
- InetSocketAddress : .getHostString ()
- InetAddress : .getLoopbackAddress ()
- 로거 : .getGlobal ()
- 동시 링크
- AbstractQueuedSynchronizer : .hasQueuedPredecessors ()
- DeflaterOutputStream : “syncFlush”를 가진 3 개의 생성자.
- 디플렉터 : .NO_FLUSH, .SYNC_FLUSH, .FULL_FLUSH, .deflate () 사 개 인수
그게 전부입니다. 특히 NIO 2.0은 존재하지 않으며 Arrays.asList는 여전히 @SafeVarargs가 아닙니다.
답변
편집 : 이것이 작성된 시점에서 최신 릴리스는 Android 9 및 Eclipse Indigo였습니다. 그때부터 상황이 바뀌 었습니다.
- 실용 답변
예, 시도했습니다. 그러나 호환성이 실제로 Java 7을 사용하는 방법 (최소한 방법은 아님)으로 레벨 6으로 제한되었으므로 이것은 훌륭한 테스트가 아닙니다.
- 먼저 다른 JDK가 설치되지 않은 컴퓨터에 JDK7을 설치했습니다. Eclipse 및 Android도 설치되지 않았습니다.
- 그런 다음 새로운 Eclipse Indigo를 설치하고 실제로 JDK 7을 사용하고 있는지 확인했습니다.
-
그런 다음 최신 버전의 Android SDK를 설치했습니다 (이 게시물 작성 당시 편집 : Honeycomb, API13). JDK 7을 찾아서 올바르게 설치했습니다. ADT도 마찬가지입니다.
-
그러나 Hello Word Android 앱을 컴파일하고 실행하려고 할 때 놀랐습니다. 호환성은 Java 6으로 강제 설정할 수없는 Java 6으로 설정되었습니다.
- 안드로이드가 아닌 프로젝트, 일반적인 Java 프로젝트로 시도했지만 설명이있었습니다. 호환성 수준은 Eclipse에 의해 제한되는 것 같습니다 (다음 이미지 하단의 메시지 참조).
내가 가진 그래서 안녕하세요을 작업하고, 다른 응용 프로그램은 더 복잡하고 사용 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 기능을 사용할 수 있는지 확실하지 않습니다 (누군가 시도 했습니까?).
그것에 대한 의견이 있으십니까? 뭔가 빠졌습니까?
답변
Eclipse 3.7.1과 함께 Android SDK v15부터 Java 7은 Android 개발에 지원 되지 않습니다 . 소스 호환성을 1.7로 설정하면 생성 된 .class 파일 호환성을 1.7로 설정해야하며, 이로 인해 Android 컴파일러에서 다음 오류가 발생합니다.
Android에는 컴파일러 준수 레벨 5.0 또는 6.0이 필요합니다. 대신 ‘1.7’을 찾았습니다. Android 도구> 프로젝트 속성 수정을 사용하십시오.
답변
@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
답변
Android 개미 기반 빌드 시스템의 코드 빌드에서 Java 7 기능을 사용하려면 custom_rules.xml
프로젝트 루트 디렉토리에 다음을 입력하십시오 .
custom_rules.xml :
<project name="custom_android_rules">
<property name="java.target" value="1.7" />
<property name="java.source" value="1.7" />
</project>