AndroidでのJava 7言語機能


188

誰かがAndroidで新しいJava 7言語機能を使ってみたかどうか疑問に思っていますか?Androidは、Javaが吐き出すバイトコードを読み取ってdexに変換することを知っています。だから私の質問はそれがJava 7のバイトコードを理解できるのでしょうか?


10
または、Java 7言語機能を使用してJava 6バイトコードにコンパイルすることもできますか?
MatrixFrog 2011

2
Android Studioは、新しいプロジェクトの作成時に通知を表示します。「minSdkVersionが19未満の場合、try-with-resourcesを使用できませんが、他のJava 7言語機能は正常です」
IgorGanapolsky

1
そうですね:)ようやくプロジェクトでJava 7を使用するようになりました。
Daniel Ryan

回答:


165

Android Studioを使用している場合、Java 7 言語はパッチなしで自動的に有効になります。リソースの試用にはAPIレベル19以上が必要であり、NIO 2.0に関するものが欠落しています。

Java 7の機能を使用できない場合は、@ Nunoの回答の編集方法を参照してくださいbuild.gradle

以下は歴史的関心のためだけのものです。


Java 7のごく一部をAndroidで確実に使用できます(注:4.1でのみテストしました)。

まず、EclipseのADTは使用できません。Javaコンパイラ1.5と1.6のみが準拠していることがハードコードされているためです。ADTを再コンパイルすることもできますが、Android全体を一緒に再コンパイルする以外に、簡単な方法はありません。

ただし、Eclipseを使用する必要はありません。たとえば、Android Studio 0.3.2IntelliJ IDEA CE、およびその他のjavacベースのIDEは、Androidへのコンパイルをサポートしており、Java 8までのコンプライアンス次のように設定できます。

  • ファイル→プロジェクト構造→モジュール→(2番目のペインでモジュールを選択)→言語レベル→(「7.0-ダイヤモンド、ARM、マルチキャッチなどを選択」)

IntelliJでJava 7を有効にする

これはJava 7 言語機能のみを許可し、改善の半分はライブラリからも得られるため、何もメリットを得ることができません。使用できる機能は、ライブラリに依存しない機能です。

  • ダイヤモンド演算子(<>
  • ストリングスイッチ
  • 複数キャッチ(catch (Exc1 | Exc2 e)
  • 数値リテラルの下線(1_234_567
  • バイナリリテラル(0b1110111

そして、これらの機能はまだ使用できませ

  • try-with-リソースの声明-それは非既存のインターフェイス「java.lang.AutoCloseable」を必要とするため(これは4.4以降で公に使用することができます)
  • @SafeVarargsアノテーション—「java.lang.SafeVarargs」が存在しないため

... "まだ" :) Androidのライブラリは1.6を対象としていますが、AndroidソースにはAutoCloseableなどのインターフェイスが含まれており、Closeableなどの従来のインターフェイスはAutoCloseableを継承しています(SafeVarargsは実際にはありません)。反射でその存在を確認できました。これらは、Javadocに@hideタグがあり、「android.jar」に含まれていないため、非表示になっています。

すでに既存の質問があります。使用可能な非表示のAPIと内部APIを使用してAndroid SDKをビルドするにはどうすればよいですか?それらのメソッドを元に戻す方法について。現在のプラットフォームの既存の「android.jar」参照をカスタマイズされたものに置き換えるだけで、多くのJava 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()
  • AutoCloseable
  • 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()
  • ConcurrentLinkedDeque
  • AbstractQueuedSynchronizer:.hasQueuedPredecessors()
  • DeflaterOutputStream:「syncFlush」を持つ3つのコンストラクター。
  • デフレータ:.NO_FLUSH、.SYNC_FLUSH、.FULL_FLUSH、.deflate()4つの引数付き

基本的にはこれですべてです。特に、NIO 2.0は存在せず、Arrays.asListはまだ@SafeVarargsではありません。


2
すばらしい答えです。将来、完全なjvmレベルのサポートが行われることを願っていnio2ます。他のグッズも間違いなく朗報です。
SD

4
AutoCloseableICSまで(またはHoneyCombまで)インターフェースがAndroidランタイムに存在しないことを言及する価値があります。そのため、パッチを適用したandroid.jarを使用しても、NoClassDefFoundError2.xシステムで受信されます。
Idolon 2013年

2
@deviant:Javaの8ラムダ使用しているので、のDalvik VMを変更する必要invokedynamicのJava 6を標的とするJVMによってサポートされていない
kennytm

2
あなたはキットカットに対してコンパイルしている場合などのtry-と資源で、Androidのスタジオ3.2のように、言語レベル7が完全にサポートされていることを更新を追加したい場合があります
JRaymond

4
リソースを試して、SDK 19(Android Kitkat)で使用できるようになりました。tools.android.com/recent/androidstudio032releasedを
Mohamed El-Nakib 2013年

70

編集:これが書かれた時点で、最新リリースはAndroid 9とEclipse Indigoでした。それ以来、物事は変わりました。

  • 実用的な答え

はい、試しました。しかし、互換性がレベル6に制限されていたため、これは優れたテストではありません。Java7を実際に使用する方法はありません(少なくとも簡単な方法はありません)。

  • 最初に、他のJDKがインストールされていないマシンにJDK7をインストールしました。EclipseとAndroidもインストールされていません。

このマシンにインストールされているのは7だけです

  • 次に、新しいEclipse Indigoをインストールし、実際にJDK 7を使用していることを確認しました(これが唯一のものであり、これが私が選択したものなので、驚いたでしょう)

このEclipseで使用されるのは7だけです

  • 次に、最新バージョンのAndroid SDKをインストールしました(編集:Honeycomb、API13、この記事の執筆時)。私のJDK 7が見つかり、正しくインストールされました。ADTについても同様です。

  • しかし、Hello Word Androidアプリをコンパイルして実行しようとすると、驚きました。互換性はJava 6に設定され、Java 7に強制する方法はありません。

互換性はJava 6に限定されています

  • Android以外のプロジェクト、通常のJavaプロジェクトを試してみましたが、説明がありました。互換性レベルはEclipseによって制限されているようです(次の画像の下部にあるメッセージを参照してください)。

Eclipseはそれ自体をレベル6の互換性に制限しています

私が持っていたので、Hello Worldのを働いて、そしてまた、他のアプリは、より複雑で使用してSQLiteListviewSensorCamera、これが唯一のJava 7の取り扱いの互換性はよくやったとAndroidで動作しているようだということを証明しています。

では、誰かが古き良きAntを使用して、上記のEclipseの制限を回避しようとしたのでしょうか。

  • 理論的な答え

とにかく、SDKは、ここで説明するように、Java 5または6で使用するように設計されています

Java 7で動作するものがあるかもしれませんが、「偶然」に動作するでしょう。DEXのビルドは適切に機能する場合と機能しない場合があり、DEXがビルドされると機能する場合と機能しない場合があります。これは、修飾されていないJDKを使用すると、定義上予測できない結果が生じるためです。

だれかが単純なJava 7の下でAndroidアプリを正常にビルドしたとしても、これはJDKの対象にはなりません。別のアプリケーションに適用された同じプロセスが失敗するか、結果のアプリケーションにそのJDKの使用に関連するバグがある可能性があります。推奨されません。

Webアプリケーションの開発に携わっている人にとっては、これはJava 5または6で構築されたWebアプリケーションをJava 4のみに対応したアプリケーションサーバー(Weblogic 8など)にデプロイするのとまったく同じです。これはうまくいくかもしれませんが、試す以外の目的で推奨できるものではありません。


1
その詳細なレビューをありがとう。したがって、Java 7言語機能を使用できないように見えますが、Java 7をJava 6として使用できます。うまくいけば、これはすぐに変更されます:)
Daniel Ryan

これはEclipseの場合です。Antでは、これはおそらく可能です。私は誰かがテストをしてくれることを望みます、そして私はそれを行うのが
面倒

はい、Vargaですが、コンパイラのバージョンの制限はAntによるものではなく、Eclipseによるものだと思います。
Shlublu

2
また、Javaの複数のバージョンを使用している場合、提供されているツールに互換性がないことに注意してください。つまり、最初にJava 6ツールのjarsignerを使用してアプリに署名し、その後java 7をインストールし、java 7に付属するjarsignerを使用してアプリの新しいバージョンに署名し、以前と同じキーストアを使用すると、署名が一致しなくなります!
ティモ

38

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機能を使用できるかどうかは不明です(誰かが試してみましたか?)。

何かコメントはありますか?何か不足していますか?


2
問題は、特にEclipseでJava 7ソースコードがJava 6クラスファイルにコンパイルされるように構成する方法です。
Randy Sugianto 'Yuku'

残っている唯一の質問は、なぜあなたも気にしないのですか?
Warpzit 2011

@Warpzitより大きな問題は、なぜ開発者がこのような混乱に
2012年

@Amitは、AndroidがJavaとは異なることに気付き、Androidと連携するために提供されているツールを使用する必要があるためです。
Warpzit 2012年

2
@Warpzit彼の唯一の問題「である?缶AndroidはJavaの7を理解する」無知は...ソリューション/答えになることはありません
アミット

12

Android SDK v15以降、Eclipse 3.7.1とともに、Java 7はAndroid開発でサポートされていません。ソースの互換性を1.7に設定するには、生成された.classファイルの互換性を1.7に設定する必要があります。これにより、Androidコンパイラで次のエラーが発生します。

Androidでは、コンパイラー準拠レベル5.0または6.0が必要です。代わりに「1.7」が見つかりました。Android Tools> Fix Project Propertiesを使用してください。


5

@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

また、注目すべきものである、数ヶ月の過去のカップルで、エリオットヒューズはAndroidの木にいくつかのコミットをした:AutoCloseable終え追加SafeVarargs再表示様々なAPI固定のThrowableのprotectedコンストラクタDXでバージョン51のクラスファイルのサポートが追加され。ですから、ようやくいくつかの進展がありました。

編集(2014年4月):

SDK 19のリリースで、android.jarに追加のAPIをパッチする必要がなくなりました。

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は、try-with-resourcesはこのAPIレベルでは使用できないと文句を言いますが、私の経験ではそうすることができます。プロジェクトは4.0.3以降のデバイスで問題なくビルドおよび実行されます。500k以上のデバイスにインストールされているアプリで、これに関する問題は発生していません。

Android Studioエラー

この警告を無視するには、以下をに追加しますlint.xml

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

1
Android Studioのコード警告で、try-with-resourcesはAPI 13の新機能であり、使用する必要があると言っているのは興味深いです。それが正しく機能しているかどうかを実際にテストする時間はありませんが。
Daniel Ryan 14

1

これを純粋なアリで動作させるのはちょっとしたことのようです。

しかし、それは私のために働きました:http : //www.informit.com/articles/article.aspx?p=1966024


1
ずっと探していました。記事をフィルタリングして人々の問題を解決するには、androidによって提供されるbuild.xmlの `<property name =" java.source "value =" 1.5 "/>`行を変更する必要があります(あなたのプロジェクト!)私にとっては/opt/android-sdk-update-manager/tools/ant/build.xml
Mateusz Kowalczyk

いいえ、必要ありません。これらのプロパティをcustom_rules.xmlで上書きできます。私の回答はこちらをご覧ください:stackoverflow.com/a/24608415/194894
Flow

1

AndroidのAntベースのビルドシステムによるコードビルドで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>

0

一部の人々は私が見つけたこのgitプロジェクトに興味があるかもしれません、それはアンドロイドでJava 7を実行することを可能にするようです。 https://github.com/yareally/Java7-on-Android

ただし、これを現在取り組んでいるプロジェクトに追加すると、リスクが高すぎます。したがって、GoogleがJava 7を正式にサポートするまで待ちます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.