แค่สงสัยว่ามีใครลองใช้คุณสมบัติภาษา Java 7 ใหม่กับ Android หรือไม่ ฉันรู้ว่า Android อ่าน bytecode ที่ Java พ่นออกมาและเปลี่ยนเป็น dex ดังนั้นฉันเดาคำถามของฉันคือมันสามารถเข้าใจ bytecode ของ Java 7 ได้หรือไม่?
แค่สงสัยว่ามีใครลองใช้คุณสมบัติภาษา Java 7 ใหม่กับ Android หรือไม่ ฉันรู้ว่า Android อ่าน bytecode ที่ Java พ่นออกมาและเปลี่ยนเป็น dex ดังนั้นฉันเดาคำถามของฉันคือมันสามารถเข้าใจ bytecode ของ Java 7 ได้หรือไม่?
คำตอบ:
หากคุณกำลังใช้Android สตูดิโอที่ Java 7 ภาษาควรเปิดใช้งานโดยอัตโนมัติโดยไม่ต้องแพทช์ใด ๆ การลองใช้ทรัพยากรต้องใช้ API ระดับ 19+ และเนื้อหา NIO 2.0 ขาดหายไป
ถ้าคุณไม่สามารถใช้ Java 7 คุณสมบัติดู@Nunoคำตอบ 's build.gradle
เกี่ยวกับวิธีการแก้ไขของคุณ
ต่อไปนี้เป็นเพื่อประโยชน์ทางประวัติศาสตร์เท่านั้น
ส่วนเล็ก ๆ ของ Java 7 สามารถใช้กับ Android ได้อย่างแน่นอน (หมายเหตุ: ฉันเพิ่งทดสอบบน 4.1)
ก่อนอื่นคุณไม่สามารถใช้ ADT ของ Eclipse ได้เนื่องจากมีการเข้ารหัสยากที่มีเพียงคอมไพเลอร์ Java 1.5 และ 1.6 เท่านั้น คุณสามารถคอมไพล์ ADT อีกครั้ง แต่ฉันพบว่าไม่มีวิธีง่ายๆในการทำเช่นนั้นนอกเหนือจากการคอมไพล์ Android ทั้งหมดใหม่ด้วยกัน
แต่คุณไม่จำเป็นต้องใช้ Eclipse ตัวอย่างเช่นAndroid Studio 0.3.2 , IntelliJ IDEA CEและ IDEs ที่ใช้ javac อื่น ๆ รองรับการคอมไพล์เป็น Android และคุณสามารถตั้งค่าความสอดคล้องได้สูงสุดถึง Java 8 ด้วย:
คุณลักษณะนี้อนุญาตให้ใช้ภาษา Java 7 เท่านั้นและคุณแทบจะไม่ได้รับประโยชน์อะไรเลยเนื่องจากการปรับปรุงครึ่งหนึ่งมาจากห้องสมุด คุณลักษณะที่คุณสามารถใช้ได้คือคุณสมบัติที่ไม่ขึ้นอยู่กับไลบรารี:
<>
)catch (Exc1 | Exc2 e)
)1_234_567
)0b1110111
)และคุณสมบัติเหล่านี้ไม่สามารถนำมาใช้เลย :
try
คำสั่งเมื่อใช้ทรัพยากร - เพราะต้องใช้อินเตอร์เฟซที่ไม่ได้มีอยู่ "java.lang.AutoCloseable" (นี้สามารถนำมาใช้ในที่สาธารณะ 4.4 ขึ้นไป)... "ยัง" :) ปรากฎว่าแม้ว่าห้องสมุด Android จะกำหนดเป้าหมายที่ 1.6 แต่ที่มาของ Android นั้นมีอินเตอร์เฟสเช่นAutoCloseableและอินเทอร์เฟซแบบดั้งเดิมเช่นCloseableนั้นสืบทอดมาจาก AutoCloseable (SafeVarargs หายไปจริงๆ) เราสามารถยืนยันการมีอยู่ของมันผ่านการสะท้อนกลับ พวกเขาถูกซ่อนไว้เพียงเพราะ Javadoc มี@hide
แท็กซึ่งทำให้ "android.jar" ไม่รวมไว้ด้วย
มีคำถามที่มีอยู่แล้วฉันจะสร้าง Android SDK ด้วย API ที่ซ่อนอยู่และภายในได้อย่างไร ในการรับวิธีการเหล่านั้นกลับมา คุณเพียงแค่ต้องแทนที่การอ้างอิง "android.jar" ที่มีอยู่ของแพลตฟอร์มปัจจุบันด้วยของเราที่กำหนดเองแล้ว Java 7 APIs จำนวนมากจะสามารถใช้ได้ (ขั้นตอนจะคล้ายกับที่อยู่ใน Eclipse ตรวจสอบโครงสร้างโครงการ→ SDK)
เพิ่มเติมจาก AutoCloseable (เฉพาะ) คุณลักษณะของไลบรารี Java 7 ต่อไปนี้ยังเปิดเผย:
นั่นคือทั้งหมดที่ โดยเฉพาะอย่างยิ่ง NIO 2.0 ไม่มีอยู่และ Arrays.asList ยังคงเป็น @SafeVarargs
nio2
และสินค้าอื่น ๆ จะเป็นข่าวดีอย่างแน่นอน
AutoCloseable
อินเทอร์เฟซที่ไม่มีอยู่ในรันไทม์ของ Android จนกว่า ICS (หรืออาจจะจนถึง HoneyComb) ดังนั้นแม้ว่าคุณจะใช้ android.jar ที่ได้รับการติดตั้งแล้วคุณจะได้รับNoClassDefFoundError
ในระบบ 2.x
invokedynamic
ซึ่งไม่รองรับโดย JVM ที่กำหนดเป้าหมายเป็น Java 6
แก้ไข: ในขณะที่เขียนนี้รุ่นล่าสุดคือ Android 9 และ Eclipse Indigo สิ่งที่มีการเปลี่ยนแปลงตั้งแต่นั้นมา
ใช่ฉันได้ลองแล้ว แต่นี่ไม่ใช่การทดสอบที่ยอดเยี่ยมเนื่องจากความเข้ากันได้ถูก จำกัด ไว้ที่ระดับ 6 โดยไม่มีวิธี (ไม่มีวิธีที่ง่ายอย่างน้อย) ในการใช้ Java 7:
จากนั้นฉันติดตั้ง 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 ที่ไม่ผ่านการรับรองจะให้ผลลัพธ์ที่ไม่คาดคิดตามคำจำกัดความ
แม้ว่าจะมีใครบางคนสร้างแอพ Android สำเร็จภายใต้ Java 7 ธรรมดาสิ่งนี้ไม่ผ่านการรับรอง JDK กระบวนการเดียวกันที่นำไปใช้กับแอปพลิเคชันอื่นอาจล้มเหลวหรือแอปพลิเคชันที่เกิดขึ้นอาจมีข้อบกพร่องที่เชื่อมโยงกับการใช้ JDK นั้น ไม่แนะนำ.
สำหรับผู้ที่มีส่วนร่วมในการพัฒนา webapps สิ่งนี้เหมือนกับการปรับใช้เว็บแอพพลิเคชั่นที่สร้างขึ้นภายใต้ Java 5 หรือ 6 ภายใต้แอพพลิเคชันเซิร์ฟเวอร์ที่มีคุณสมบัติสำหรับ Java 4 เท่านั้น (ตัวอย่างเช่น Weblogic 8) สิ่งนี้อาจใช้งานได้ แต่นี่ไม่ใช่สิ่งที่สามารถแนะนำเพื่อวัตถุประสงค์อื่นได้
อ้างอิงจาก dalvikvm.com:
dx ที่รวมอยู่ใน Android SDK แปลงไฟล์ Java Class ของคลาส Java ที่คอมไพล์โดยคอมไพเลอร์ Java ปกติเป็นรูปแบบไฟล์คลาสอื่น (รูปแบบ. dex)
นั่นหมายความว่าไฟล์ต้นฉบับ. java ไม่สำคัญว่าเป็นไฟล์. class bytecode เท่านั้น
เท่าที่ผมทราบเพียงinvokedynamicถูกเพิ่มลงใน bytecode JVM ใน Java 7 ส่วนที่เหลือเป็นเข้ากันได้กับภาษา Java 6. Java ตัวเองไม่ได้ใช้invokedynamic คุณสมบัติใหม่อื่น ๆ เช่นคำสั่งswitchโดยใช้String s หรือ multi- catchเป็นเพียงน้ำตาล syntatic และไม่ต้องการการเปลี่ยนรหัสไบต์ ตัวอย่างเช่น multi- catchเพียงคัดลอกcatch -block สำหรับแต่ละข้อยกเว้นที่เป็นไปได้
ปัญหาเดียวที่ควรเกิดขึ้นคือคลาสใหม่ที่นำเสนอใน Java 7 หายไปใน Android เช่นAutoCloseableดังนั้นฉันไม่แน่ใจว่าคุณสามารถใช้คุณสมบัติลองด้วยทรัพยากรได้หรือไม่
ความคิดเห็นใด ๆ ฉันพลาดอะไรไปรึเปล่า?
ในฐานะของ Android SDK v15 พร้อมกับ Eclipse 3.7.1, Java 7 ไม่ได้รับการสนับสนุนสำหรับการพัฒนา Android การตั้งค่าความเข้ากันได้ของแหล่งข้อมูลให้กับ 1.7 คำสั่งตั้งค่าความเข้ากันได้ของไฟล์. class เป็น 1.7 ซึ่งนำไปสู่ข้อผิดพลาดต่อไปนี้โดยคอมไพเลอร์ Android:
Android ต้องการคอมไพเลอร์ตามระดับ 5.0 หรือ 6.0 พบ '1.7' แทน โปรดใช้เครื่องมือ Android> แก้ไขคุณสมบัติของโครงการ
หากต้องการขยายคำตอบข้างต้นโดย @KennyTM หากคุณกำหนดเป้าหมายเป็น 4.0.3 ขึ้นไป ( minSdkVersion = 15 ) คุณสามารถใช้ API ที่ซ่อนอยู่ได้โดยเพิ่มคลาสไม่กี่คลาสลงใน android.jar SDK เป้าหมายของคุณ
เมื่อคุณทำสิ่งนี้แล้วคุณสามารถใช้การลองกับทรัพยากรใน Closeable ใด ๆ รวมทั้งใช้ AutoCloseable ในคลาสของคุณเอง
ฉันได้สร้างรหัสไปรษณีย์ที่มีซอร์สและไบนารีของคลาสทั้งหมดที่จำเป็นต้องแก้ไขใน android.jar เพื่อให้ API เหล่านี้พร้อมใช้งาน คุณเพียงแค่ต้องแกะมันออกและเพิ่มไบนารีไปยัง
android-sdk / platforms / android-NN / android.jar
คุณสามารถดาวน์โหลดได้จากที่นี่: http://db.tt/kLxAYWbr
ยังมีโน้ตคือว่าในคู่ที่ผ่านมาของเดือน, เอลเลียตฮิวจ์สได้ทำกระทำไม่กี่ต้นไม้ Android: เสร็จปิด AutoCloseable , เพิ่ม SafeVarargs , APIs ต่างๆ unhidden , คงคอนสตรัคได้รับการคุ้มครอง Throwable ของและเพิ่มการสนับสนุนสำหรับไฟล์ระดับรุ่น 51 DX . ดังนั้นในที่สุดก็มีความคืบหน้าบางอย่างเกิดขึ้น
แก้ไข (เมษายน 2014):
ด้วยการเปิดตัว SDK 19 ไม่จำเป็นต้องแก้ไข android.jar อีกต่อไปกับ API เพิ่มเติม
วิธีที่ดีที่สุดในการใช้ทรัพยากรทดลองใน Android Studio สำหรับแอปที่มีเป้าหมายที่ 4.0.3 ขึ้นไป ( minSdkVersion = 15 ) คือการเพิ่มสิ่งต่อไปนี้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
custom_rules.xml
ดูคำตอบของฉันที่นี่: stackoverflow.com/a/24608415/194894
เพื่อที่จะใช้คุณสมบัติ Java 7 ในการสร้างรหัสโดยระบบการสร้างบนพื้นฐานของ Android เพียงวางสิ่งต่อไปนี้ใน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>
บางคนอาจสนใจโครงการ git นี้ที่ฉันพบซึ่งดูเหมือนว่าอนุญาตให้เรียกใช้ Java 7 บน Android https://github.com/yareally/Java7-on-Android
อย่างไรก็ตามมีความเสี่ยงมากเกินไปหากฉันเพิ่มสิ่งนี้ลงในโครงการปัจจุบันที่ฉันทำงานอยู่ ดังนั้นฉันจะรอจนกว่า Google จะสนับสนุน Java 7 อย่างเป็นทางการ