誰かがAndroidで新しいJava 7言語機能を使ってみたかどうか疑問に思っていますか?Androidは、Javaが吐き出すバイトコードを読み取ってdexに変換することを知っています。だから私の質問はそれがJava 7のバイトコードを理解できるのでしょうか?
誰かがAndroidで新しいJava 7言語機能を使ってみたかどうか疑問に思っていますか?Androidは、Javaが吐き出すバイトコードを読み取ってdexに変換することを知っています。だから私の質問はそれがJava 7のバイトコードを理解できるのでしょうか?
回答:
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.2、IntelliJ IDEA CE、およびその他のjavacベースのIDEは、Androidへのコンパイルをサポートしており、Java 8までのコンプライアンスを次のように設定できます。
これはJava 7 言語機能のみを許可し、改善の半分はライブラリからも得られるため、何もメリットを得ることができません。使用できる機能は、ライブラリに依存しない機能です。
<>
)catch (Exc1 | Exc2 e)
)1_234_567
)0b1110111
)そして、これらの機能はまだ使用できません:
try
-with-リソースの声明-それは非既存のインターフェイス「java.lang.AutoCloseable」を必要とするため(これは4.4以降で公に使用することができます)... "まだ" :) 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 ライブラリ機能も表示されます。
基本的にはこれですべてです。特に、NIO 2.0は存在せず、Arrays.asListはまだ@SafeVarargsではありません。
nio2
ます。他のグッズも間違いなく朗報です。
AutoCloseable
ICSまで(またはHoneyCombまで)インターフェースがAndroidランタイムに存在しないことを言及する価値があります。そのため、パッチを適用したandroid.jarを使用しても、NoClassDefFoundError
2.xシステムで受信されます。
invokedynamic
のJava 6を標的とするJVMによってサポートされていない
編集:これが書かれた時点で、最新リリースはAndroid 9とEclipse Indigoでした。それ以来、物事は変わりました。
はい、試しました。しかし、互換性がレベル6に制限されていたため、これは優れたテストではありません。Java7を実際に使用する方法はありません(少なくとも簡単な方法はありません)。
次に、最新バージョンのAndroid SDKをインストールしました(編集:Honeycomb、API13、この記事の執筆時)。私のJDK 7が見つかり、正しくインストールされました。ADTについても同様です。
しかし、Hello Word Androidアプリをコンパイルして実行しようとすると、驚きました。互換性はJava 6に設定され、Java 7に強制する方法はありません。
私が持っていたので、Hello Worldのを働いて、そしてまた、他のアプリは、より複雑で使用してSQLite
、Listview
、Sensor
とCamera
、これが唯一の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など)にデプロイするのとまったく同じです。これはうまくいくかもしれませんが、試す以外の目的で推奨できるものではありません。
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
また、注目すべきものである、数ヶ月の過去のカップルで、エリオットヒューズは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以上のデバイスにインストールされているアプリで、これに関する問題は発生していません。
この警告を無視するには、以下をに追加します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
一部の人々は私が見つけたこのgitプロジェクトに興味があるかもしれません、それはアンドロイドでJava 7を実行することを可能にするようです。 https://github.com/yareally/Java7-on-Android
ただし、これを現在取り組んでいるプロジェクトに追加すると、リスクが高すぎます。したがって、GoogleがJava 7を正式にサポートするまで待ちます。