programing

Android의 Java 7 언어 기능

new-time 2020. 5. 14. 22:32
반응형

Android의 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까지 준수를 설정할 수 있습니다.

  • 파일 → 프로젝트 구조 → 모듈 → (두 번째 창에서 모듈 선택) → 언어 수준 → ( "7.0-다이아몬드, ARM, 멀티 캐치 등"선택)

IntelliJ에서 Java 7 사용

기능

은 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도 설치되지 않았습니다.

7은이 머신에 설치된 유일한 제품입니다

  • 그런 다음 새로운 Eclipse Indigo를 설치하고 실제로 JDK 7을 사용하고 있는지 확인했습니다 (이것이 유일한 것이고 이것이 선택한 것이므로 놀랐을 것입니다)

7은이 이클립스가 사용하는 유일한 제품입니다

  • 그런 다음 최신 버전의 Android SDK를 설치했습니다 (이 게시물 작성 당시 편집 : Honeycomb, API13). JDK 7을 찾아서 올바르게 설치했습니다. ADT와 동일합니다.
  • 그러나 Hello Word Android 앱을 컴파일하고 실행하려고 할 때 놀랐습니다. 호환성은 Java 6으로 강제 설정할 수없는 Java 6으로 설정되었습니다.

호환성은 Java 6으로 제한됩니다

  • I tried with a non-Android project, a regular Java one, and I had the explanation. The compatibility level seems to be limited by Eclipse (see the message at bottom of the following image):

Eclipse는 레벨 6 호환성으로 제한됩니다.

So I had Hello World working, and also other apps, more complicated and using SQLite, Listview, Sensor and Camera, but this only proves that the compatibility handling of Java 7 seems to be well done and working with Android.

So, did someone try with the good old Ant, to bypass the Eclipse limitation seen above?

  • Theroetical answer

Anyway, the SDK is designed to be used with Java 5 or 6, as explained here.

We may have something working with Java 7, but it would be working "by accident". The building of the DEX may work properly or not, and once the DEX built, it may work or not. This because using a non-qualified JDK gives unpredictable results by definition.

Even if someone has succesfully built an Android app under plain Java 7, this does not qualify the JDK. The same process applied to another application may fail, or the resulting application may have bugs tied to the use of that JDK. Not recommended.

For those who are involved on webapps development, this exactly the same as deploying a web application built under Java 5 or 6 under an application server qualified for Java 4 only (let's say Weblogic 8 for example). This may work, but this is not something that can be recommended for other purposes than trying.


Quote from dalvikvm.com:

dx, included in the Android SDK, transforms the Java Class files of Java classes compiled by a regular Java compiler into another class file format (the .dex format)

That means, the .java source file does not matter, it's only the .class bytecode.

As far as I know, only invokedynamic was added to the JVM bytecode in Java 7, the rest is compatible to Java 6. The Java language itself does not use invokedynamic. Other new features, like the switch statement using Strings or the multi-catch are just syntatic sugar and did not require byte code changes. For example, the multi-catch just copies the catch-block for each possible exception.

The only problem should be that the new classes introduced in Java 7 are missing in Android, like AutoCloseable, so I'm not sure if you can use the try-with-resources feature (somebody tried it?).

Any comments on that? Am I missing something?


As of the Android SDK v15, along with Eclipse 3.7.1, Java 7 is not supported for Android development. Setting the source compatibility to 1.7 mandates setting the generated .class file compatibility to 1.7, which leads to the following error by the Android compiler:

Android requires compiler compliance level 5.0 or 6.0. Found '1.7' instead. Please use Android Tools > Fix Project Properties.


To expand on the above answer by @KennyTM, if you are targeting 4.0.3 and above (minSdkVersion=15), you can use the hidden APIs by adding a few classes to your target's SDK android.jar.

Once you do this, you can use try-with-resources on any Closeable, as well as implement AutoCloseable in your own classes.

I've made a zip containing sources and binaries of all the classes that needed to be modified in android.jar to make these APIs available. You just need to unpack it and add the binaries to your
android-sdk/platforms/android-NN/android.jar

You can download it from here: http://db.tt/kLxAYWbr

Also of note is that, in the past couple of months, Elliott Hughes has made a few commits to the Android tree: finished off AutoCloseable, added SafeVarargs, unhidden various APIs, fixed Throwable's protected constructor and added support for version 51 class files in dx. So, there is finally some progress going on.

Edit (April 2014):

With the release of SDK 19 it is no longer necessary to patch android.jar with the additional APIs.

The best method to use try-with-resources in Android Studio for an app that targets 4.0.3 and above (minSdkVersion=15) is add the following compileOptions to your 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 will complain that try-with-resources can't be used with this API level, but my experience is that it can. The project will build and run without issue on devices with 4.0.3 and above. I've experienced no issues with this, with an app that has been installed into 500k+ devices.

안드로이드 스튜디오 오류

To ignore this warning, add the following to your lint.xml:

<issue id="NewApi">
    <ignore regexp="Try-with-resources requires API level 19"/>
</issue>

It seems that getting this to work with pure ant is a bit of a kludge.

But it worked for me: http://www.informit.com/articles/article.aspx?p=1966024


In order to use Java 7 features in code build by Android's ant based build system, simply put the following in your custom_rules.xml in your projects root directory:

custom_rules.xml:

<project name="custom_android_rules">
    <property name="java.target" value="1.7" />
    <property name="java.source" value="1.7" />
</project>

일부 사람들은 내가 찾은이 자식 프로젝트에 관심이있을 수 있습니다. 안드로이드에서 Java 7을 실행할 수있는 것 같습니다.

https://github.com/yareally/Java7-on-Android

그러나 현재 작업중 인 프로젝트에 이것을 추가하면 너무 위험합니다. Google이 공식적으로 Java 7을 지원할 때까지 기다립니다.참고 URL :

https://stackoverflow.com/questions/7153989/java-7-language-features-with-android

반응형