Android ile Java 7 dil özellikleri


188

Sadece Android ile yeni Java 7 dil özelliklerini kullanmayı deneyen olup olmadığını merak mı ediyorsunuz? Android'in Java'nın tükettiği bayt kodunu okuduğunu ve dex'e dönüştürdüğünü biliyorum. Sanırım sorum şu: Java 7'nin bayt kodunu anlayabiliyor mu?


10
Alternatif olarak, Java 7 dil özelliklerini kullanabilir, ancak Java 6 bayt koduna derleyebilirsiniz?
MatrixFrog

2
Android Studio şimdi yeni bir proje oluştururken size bir bildirimde bulunacak: "minSdkVersion 19'dan az olduğunda, kaynaklarla denemeyi kullanamazsınız, ancak diğer Java 7 dil özellikleri iyi"
IgorGanapolsky

1
Evet biliyorum :) Sonunda projemizde Java 7 kullanıyoruz.
Daniel Ryan

Yanıtlar:


165

Android Studio kullanıyorsanız , Java 7 dili herhangi bir yama olmadan otomatik olarak etkinleştirilmelidir. Kaynakla deneme API Düzeyi 19+ gerektirir ve NIO 2.0 öğeleri eksik.

Java 7 özelliklerini kullanamıyorsanız, @Nuno'nun , bilgisayarınızı nasıl düzenleyeceğiniz konusundaki cevabına bakın build.gradle.

Aşağıdakiler sadece tarihsel ilgi içindir.


Java 7'nin küçük bir kısmı kesinlikle Android ile kullanılabilir (not: Sadece 4.1'de test ettim).

Her şeyden önce, Eclipse'nin ADT'sini kullanamazsınız çünkü sadece Java derleyici 1.5 ve 1.6'nın uyumlu olması zor kodlanmıştır . ADT'yi yeniden derleyebilirsiniz, ancak tüm Android'i birlikte yeniden derlemenin dışında bunu yapmanın basit bir yolu olmadığını düşünüyorum.

Ama Eclipse kullanmanıza gerek yok. Örneğin, Android Studio 0.3.2 , IntelliJ IDEA CE ve diğer javac tabanlı IDE'ler Android'e derlemeyi destekler ve aşağıdakilerle Java 8'e kadar uyumluluğu ayarlayabilirsiniz:

  • Dosya → Proje Yapısı → Modüller → (2. bölmeden modülü seçin) → Dil seviyesi → ("7.0 - Diamonds, ARM, çoklu yakalama vb." Seçeneğini seçin)

IntelliJ'de Java 7'yi etkinleştirme

Bu sadece Java 7 dil özelliklerine izin verir ve iyileştirmenin yarısı kütüphaneden geldiğinden herhangi bir şeyden neredeyse hiç yararlanamazsınız. Kullanabileceğiniz özellikler kütüphaneye bağlı olmayan özelliklerdir:

  • Elmas operatörü ( <>)
  • Dize anahtarı
  • Çoklu yakalama ( catch (Exc1 | Exc2 e))
  • Sayı değişmezinde alt çizgi ( 1_234_567)
  • İkili değişmez değerler ( 0b1110111)

Ve bu özellikler henüz kullanılamaz :

  • try-With-kaynaklar deyimi - bu var olmayan bir arayüz "java.lang.AutoCloseable" gerektirdiğinden (bu 4.4+ herkes tarafından kullanılabilir)
  • @SafeVarargs ek açıklaması - "java.lang.SafeVarargs" mevcut olmadığından

... "yet" :) Android kütüphanesi 1.6 için hedef alsa da, Android kaynağı AutoCloseable gibi arayüzler içeriyor ve Closeable gibi geleneksel arayüzler AutoCloseable'den miras alıyor (SafeVarargs gerçekten eksik). Varlığını yansıtarak doğrulayabiliriz. Javadoc, @hide"android.jar" öğesinin bunları içermemesine neden olan etikete sahip olmasından dolayı gizlidir .

Zaten mevcut soru var Android SDK'yı mevcut gizli ve dahili API'lerle nasıl oluşturabilirim? bu yöntemleri nasıl geri alabileceğimiz konusunda. Mevcut Platformun mevcut "android.jar" referansını özelleştirilmiş olanımızla değiştirmeniz yeterlidir , ardından Java 7 API'lerinin çoğu kullanılabilir hale gelir (prosedür Eclipse'deki ile benzerdir. Proje Yapısı → SDK'ları kontrol edin.)

Otomatik Kapanma özelliğine ek olarak, (yalnızca) aşağıdaki Java 7 kitaplığı özellikleri de gösterilir:

  • ConcurrentModificationException, LinkageError ve AssertionError içindeki istisna zincirleme kurucuları
  • Temel öğeler için statik .compare () yöntemleri: Boolean.compare (), Byte.compare (), Short.compare (), Character.compare (), Integer.compare (), Long.compare ().
  • Para Birimi : .getAvailableCurrencies (), .getDisplayName () (ancak .getNumericCode () olmadan )
  • BitSet : .previousSetBit (), .previousClearBit (), .valueOf (), .toLongArray (), .toByteArray ()
  • Koleksiyonlar : .emptyEnumeration (), .emptyIterator (), .emptyListIterator ()
  • AutoCloseable
  • Throwable : .addSuppressed (), .getSuppressed () ve 4 değişkenli yapıcı
  • Karakter : .compare (), .isSurrogate (), .getName (), .highSurrogate (), .lowSurrogate (), .isBmpCodePoint () (ancak .isAlphabetic () ve .isIdeographic () olmadan )
  • Sistem: .lineSeparator () (belgesiz?)
  • java.lang.reflect.Modifier : .classModifiers (), .constructorModifiers (), .fieldModifiers (), .interfaceModifiers (), .methodModifiers ()
  • NetworkInterface : .getIndex (), .getByIndex ()
  • InetSocketAddress : .getHostString ()
  • InetAddress : .getLoopbackAddress ()
  • Kaydedici : .getGlobal ()
  • ConcurrentLinkedDeque
  • AbstractQueuedSynchronizer : .hasQueuedPredecessors ()
  • DeflaterOutputStream : "syncFlush" olan 3 kurucu.
  • Deflater : .NO_FLUSH, .SYNC_FLUSH, .FULL_FLUSH, .deflate () 4 argümanla

Temelde hepsi bu. Özellikle, NIO 2.0 mevcut değildir ve Arrays.asList hala @SafeVarargs değildir.


2
Mükemmel cevap. Umarım yakında jvm seviyesi desteği yakında gerçekleşir nio2ve diğer güzellikler kesinlikle iyi bir haber olacaktır.
SD

4
AutoCloseableArayüzün ICS'ye kadar (veya belki HoneyComb'a kadar) Android çalışma zamanında mevcut olmadığını belirtmek gerekir. Bu yüzden yamalı android.jar kullansanız bile NoClassDefFoundError2.x sisteminde alacaksınız .
Idolon

2
@deviant: Java 8 lambda, invokedynamicJava 6'yı hedefleyen JVM tarafından desteklenmediği için Dalvik VM'yi değiştirmeyi gerektirir .
kennytm

2
KitKat
JRaymond

4
SDK 19 (Android Kitkat) üzerinde artık kaynaklarla deneme kullanılabilir. bkz. tools.android.com/recent/androidstudio032 yayımlandı
Mohamed El-Nakib

70

EDIT: Bu yazıldığı anda, en son sürüm Android 9 ve Eclipse Indigo idi. O zamandan beri bir şey değişti.

  • Pratik cevap

Evet, denedim. Ancak bu, java 7'yi gerçekten kullanmanın hiçbir yolu olmadan (en azından basit bir yol yok) seviye 6 ile sınırlı olduğu için bu harika bir test değil:

  • İlk olarak başka bir JDK yüklü olmayan bir makineye bir JDK7 yükledim - Eclipse ve Android de yüklü değil:

7 bu makinede kurulu tek

  • Sonra yepyeni bir Eclipse Indigo yükledim ve aslında JDK 7'yi kullandığını kontrol ettim (bu tek kişi olduğu için ve bu seçtiğim için şaşırırdım)

7, bu Tutulma tarafından kullanılan tek

  • Sonra Android SDK'nın en son sürümünü yükledim (EDIT: Honeycomb, API13, bu yazının yazıldığı sırada). JDK 7'mi buldu ve düzgün şekilde kuruldu. Aynısı ADT için de geçerli.

  • Ama bir Hello Word Android uygulamasını derlemeye ve çalıştırmaya çalışırken bir sürprizim vardı. Uyumluluk Java 6'ya ayarlandı ve Java 7'ye zorlama yolu yoktu:

Uyumluluk Java 6 ile sınırlıdır

  • Android olmayan bir proje, normal bir Java projesi ile denedim ve açıklama yaptım. Uyumluluk düzeyi Eclipse tarafından sınırlı görünmektedir (aşağıdaki görüntünün altındaki mesaja bakın):

Tutulma kendini seviye 6 uyumluluğuyla sınırlar

Ben Yani Hello World çalışan ve aynı zamanda diğer uygulamalar, daha karmaşık ve kullanma SQLite, Listview, Sensorve Camerafakat bu sadece Java 7'nin taşıma uyumluluğu aferin ve Android ile çalışıyor gibi görünüyor kanıtlıyor.

Peki, birisi yukarıda görülen Eclipse sınırlamasını atlamak için iyi eski Ant ile denedi mi?

  • Teorik cevap

Her neyse, SDK burada açıklandığı gibi Java 5 veya 6 ile kullanılmak üzere tasarlanmıştır .

Java 7 ile çalışan bir şeyimiz olabilir, ancak "kazayla" işe yarayacaktır. DEX'in inşası düzgün çalışabilir veya çalışmayabilir ve DEX kurulduktan sonra çalışabilir veya çalışmayabilir. Çünkü kalifiye olmayan bir JDK kullanmak tanım gereği beklenmedik sonuçlar verir.

Birisi düz Java 7 altında başarılı bir şekilde bir Android uygulaması oluşturmuş olsa bile, bu JDK'yı nitelendirmez. Başka bir uygulamaya uygulanan aynı işlem başarısız olabilir veya sonuçta ortaya çıkan uygulama, söz konusu JDK'nın kullanımına bağlı hatalara sahip olabilir. Tavsiye edilmez.

Webapps geliştirmeye dahil olanlar için bu, Java 5 veya 6 altında oluşturulmuş bir web uygulamasını yalnızca Java 4 için nitelikli bir uygulama sunucusu altında dağıtmakla aynıdır (örneğin Weblogic 8 diyelim). Bu işe yarayabilir, ancak bu denemek yerine başka amaçlar için önerilebilecek bir şey değildir.


1
Bu detaylı inceleme için teşekkürler. Yani Java 7 dil özelliklerini kullanamıyorsunuz ama Java 7'yi Java 6 olarak kullanıyorsunuz. Umarım bu yakında değişir :)
Daniel Ryan

Eclipse ile. Ant ile bu muhtemelen mümkündür. Umarım birisi testi yapar ve bunu yapmak için çok tembel olduğum için kendimi suçluyorum :)
Shlublu

Evet Varga, ama derleyici sürüm sınırlamasının Ant'den değil Eclipse'den geldiğini düşünüyorum.
Shlublu

2
Ayrıca, Java'nın birden çok sürümüyle oynamanız durumunda sağlanan araçların uyumlu olmadığını unutmayın. Demek istediğim, önce uygulamanızı java 6 araçlarından jarsigner ile imzalayıp daha sonra java 7'yi yüklediyseniz ve java 7 ile gelen jarsigner ve daha önce imzalananlarla aynı anahtar deposuyla yeni bir sürüm imzaladıysanız !
Timo

38

Dalvikvm.com'dan alıntı:

Android SDK'sında bulunan dx, normal bir Java derleyicisi tarafından derlenen Java sınıflarının Java Sınıfı dosyalarını başka bir sınıf dosyası biçimine (.dex biçimi) dönüştürür

Yani, .java kaynak dosyası önemli değil, sadece .class bayt kodu.

Bildiğim kadarıyla , Java 7'deki JVM bayt koduna yalnızca invüinamik eklenmiştir, geri kalanı Java 6 ile uyumludur. Java dilinin kendisi invokedynamic kullanmaz . String s veya multi- catch kullanan switch deyimi gibi diğer yeni özellikler sadece sözdizimsel şekerdir ve bayt kodu değişikliği gerektirmez. Örneğin, çoklu yakalama her olası istisna için catch- bloğunu kopyalar .

Tek sorun, Java 7'de tanıtılan yeni sınıfların AutoCloseable gibi Android'de eksik olması gerektiğinden, try -with-resources özelliğini kullanıp kullanamayacağınızdan emin değilim (birisi denedi mi?).

Bununla ilgili herhangi bir yorumunuz var mı? Bir şey mi kaçırıyorum?


2
Şimdi sorun, Java 7 kaynak kodlarının Java 6 sınıf dosyalarına, özellikle de tutulmada derleneceği şekilde nasıl yapılandırılır?
Randy Sugianto 'Yuku'

Geriye kalan tek soru neden rahatsız oluyorsun?
Warpzit

@ Büyük soru şu olmalıdır: Bir geliştirici neden tüm bu karışıklıktan rahatsız olmaz?
Amit

@Amit, Android'in Java'dan farklı olduğunu fark ettiği için ve Android ile çalışmak için sunulan araçları kullanması gerekiyor.
Warpzit

2
@Warpzit Tek sorusu " Android java 7'i anlayabilir mi? " Cehalet asla bir çözüm / cevap değildir ...
Amit

12

Android SDK v15 itibariyle Eclipse 3.7.1 ile birlikte Java 7 edilir değil Android geliştirme için destekledi. Kaynak uyumluluğunu 1.7 olarak ayarlamak, oluşturulan .class dosya uyumluluğunu 1.7 olarak ayarlamayı gerektirir ve bu da Android derleyicisi tarafından aşağıdaki hataya neden olur:

Android, derleyici uyumluluk düzeyi 5.0 veya 6.0 gerektirir. Bunun yerine '1.7' bulundu. Lütfen Android Araçları> Proje Özelliklerini Onar'ı kullanın.


5

Yukarıdaki cevabı @KennyTM ile genişletmek için, 4.0.3 ve üzerini hedefliyorsanız ( minSdkVersion = 15 ), hedefinizin SDK android.jar'ına birkaç sınıf ekleyerek gizli API'leri kullanabilirsiniz.

Bunu yaptıktan sonra, herhangi bir Closeable üzerinde kaynaklarla deneme özelliğini kullanabilir ve kendi sınıflarınızda AutoCloseable uygulayabilirsiniz.

Bu API'leri kullanılabilir hale getirmek için android.jar'da değiştirilmesi gereken tüm sınıfların kaynaklarını ve ikili dosyalarını içeren bir zip yaptım. Sadece paketini açmanız ve ikili dosyaları
android-sdk / platformlar / android-NN / android.jar'a eklemeniz yeterlidir.

Buradan indirebilirsiniz: http://db.tt/kLxAYWbr

Ayrıca Not yani ay son birkaç Elliott Hughes Android ağacına birkaç hareketin yaptı: AutoCloseable bitirdi , katma SafeVarargs , unhidden çeşitli API'ler , sabit Throwable korunan yapıcı ve dx sürüm 51 sınıf dosyaları desteği eklendi . Sonunda, bazı ilerlemeler kaydediliyor.

Düzenleme (Nisan 2014):

SDK 19'un piyasaya sürülmesiyle artık android.jar'ı ek API'lerle yamalamak gerekmiyor.

Bir uygulama için kullanıma deneyin-ile-kaynaklar Android Studio için en iyi yöntem hedefleri 4.0.3 ve (yukarıda olduğu minSdkVersion'ın = 15 ) Aşağıdaki ekleyin edilir compileOptionsadresinden Müşteri 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, kaynaklarla denemenin bu API düzeyinde kullanılamayacağından şikayet edecek, ancak benim deneyimim bunu yapabileceğidir. Proje, 4.0.3 ve üstü cihazlarda sorunsuz bir şekilde oluşturulacak ve çalışacaktır. 500k + cihazlara yüklenmiş bir uygulama ile bununla ilgili hiçbir sorun yaşamadım.

Android Studio hatası

Bu uyarıyı yok saymak için aşağıdakileri ekleyin lint.xml:

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

1
Android Studio kod uyarısının, kaynaklarla denemenin API 13'te yeni olduğunu ve ilginç olması gerektiğini ilginç buluyorum. Gerçi doğru çalışıp çalışmadığını test etmek için zamanınız yok.
Daniel Ryan

1

Bunun saf karınca ile çalışmasını sağlamak bir miktar çamurdur.

Ama benim için çalıştı: http://www.informit.com/articles/article.aspx?p=1966024


1
Bunu uzun süre aradım. Makaleyi filtreleyerek kullanıcıların sorununu kesmek için android tarafından sağlanan build.xml dosyasındaki `` <property name = "java.source" value = "1.5" /> `satırını değiştirmeniz gerekir. senin projen!). Benim için /opt/android-sdk-update-manager/tools/ant/build.xml oldu
Mateusz Kowalczyk

Hayır. Bu özelliklerin üzerine yazabilirsiniz custom_rules.xml, cevabımı buradan görebilirsiniz: stackoverflow.com/a/24608415/194894
Flow

1

Android'in karınca tabanlı derleme sistemi tarafından kod oluşturmada Java 7 özelliklerini kullanmak için custom_rules.xml, projelerinizin kök dizinine aşağıdakileri eklemeniz yeterlidir :

custom_rules.xml:

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

0

Bazı insanlar bulduğum bu git projesiyle ilgilenebilir, bu Java 7'yi android üzerinde çalıştırmaya izin veriyor gibi görünüyor. https://github.com/yareally/Java7-on-Android

Ancak bunu üzerinde çalıştığım projeye eklersem çok fazla risk. Bu yüzden Google'ın Java 7'yi resmi olarak desteklemesini bekleyeceğim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.