Chỉ tự hỏi nếu có ai đã thử sử dụng các tính năng ngôn ngữ Java 7 mới với Android? Tôi biết rằng Android đọc mã byte mà Java phát ra và biến nó thành dex. Vì vậy, tôi đoán câu hỏi của tôi là nó có thể hiểu mã byte của Java 7 không?
Chỉ tự hỏi nếu có ai đã thử sử dụng các tính năng ngôn ngữ Java 7 mới với Android? Tôi biết rằng Android đọc mã byte mà Java phát ra và biến nó thành dex. Vì vậy, tôi đoán câu hỏi của tôi là nó có thể hiểu mã byte của Java 7 không?
Câu trả lời:
Nếu bạn đang sử dụng Android Studio , ngôn ngữ Java 7 sẽ được bật tự động mà không cần bất kỳ bản vá nào. Thử tài nguyên yêu cầu API cấp 19+ trở lên và nội dung NIO 2.0 bị thiếu.
Nếu bạn không thể sử dụng các tính năng của Java 7, hãy xem câu trả lời của @Nuno về cách chỉnh sửa của bạn build.gradle
.
Sau đây chỉ dành cho lợi ích lịch sử.
Một phần nhỏ của Java 7 chắc chắn có thể được sử dụng với Android (lưu ý: Tôi mới chỉ thử nghiệm trên 4.1).
Trước hết, bạn không thể sử dụng ADT của Eclipse vì nó được mã hóa cứng mà chỉ có trình biên dịch Java 1.5 và 1.6 tuân thủ. Bạn có thể biên dịch lại ADT nhưng tôi thấy không có cách nào đơn giản để làm điều đó ngoài việc biên dịch lại toàn bộ Android với nhau.
Nhưng bạn không cần sử dụng Eclipse. Chẳng hạn, Android Studio 0.3.2 , IntelliJ IDEA CE và các IDE dựa trên javac khác hỗ trợ biên dịch cho Android và bạn có thể đặt tuân thủ ngay cả lên tới Java 8 với:
Điều này chỉ cho phép các tính năng ngôn ngữ Java 7 và bạn khó có thể hưởng lợi từ bất cứ điều gì vì một nửa cải tiến cũng đến từ thư viện. Các tính năng bạn có thể sử dụng là những tính năng không phụ thuộc vào thư viện:
<>
)catch (Exc1 | Exc2 e)
)1_234_567
)0b1110111
)Và các tính năng này không thể sử dụng được nêu ra :
try
-with-resource - bởi vì nó yêu cầu giao diện không tồn tại "java.lang.AutoClosizable" (điều này có thể được sử dụng công khai trong 4.4+)... "Chưa" :) Hóa ra, mặc dù thư viện của Android đang nhắm mục tiêu cho 1.6, nhưng nguồn Android có chứa các giao diện như AutoClosizable và các giao diện truyền thống như Closizable thừa hưởng từ AutoClosizable (tuy nhiên SafeVarargs thực sự bị thiếu). Chúng ta có thể xác nhận sự tồn tại của nó thông qua sự phản chiếu. Chúng bị ẩn đơn giản vì Javadoc có @hide
thẻ, khiến "android.jar" không bao gồm chúng.
Đã có câu hỏi hiện tại Làm cách nào để xây dựng SDK Android với các API ẩn và nội bộ có sẵn? về cách lấy lại các phương thức đó. Bạn chỉ cần thay thế tham chiếu "android.jar" hiện có của Nền tảng hiện tại bằng nền tảng tùy chỉnh của chúng tôi, sau đó nhiều API Java 7 sẽ có sẵn (quy trình tương tự như trong Eclipse. Kiểm tra cấu trúc dự án → SDK.)
Ngoài bổ sung cho AutoClosizable, (chỉ) các tính năng thư viện Java 7 sau đây cũng được tiết lộ:
Về cơ bản là tất cả. Cụ thể, NIO 2.0 không tồn tại và Arrays.asList vẫn không phải là @SafeVarargs.
nio2
và những điều tốt đẹp khác chắc chắn sẽ là một tin tốt.
AutoCloseable
giao diện đó không tồn tại trong thời gian chạy Android cho đến khi có ICS (hoặc có lẽ cho đến HoneyComb). Vì vậy, ngay cả khi bạn sử dụng android.jar đã vá, bạn sẽ nhận được NoClassDefFoundError
trên hệ thống 2.x.
invokedynamic
không được hỗ trợ bởi JVM nhắm mục tiêu Java 6.
EDIT: Tại thời điểm này được viết, bản phát hành mới nhất là Android 9 và Eclipse Indigo. Điều đã thay đổi kể từ đó.
Vâng, tôi đã thử. Nhưng đây không phải là một thử nghiệm tuyệt vời vì khả năng tương thích bị giới hạn ở cấp 6 mà không có cách nào (ít nhất là cách đơn giản) để thực sự sử dụng java 7:
Sau đó, tôi đã cài đặt phiên bản Android SDK mới nhất (EDIT: Honeycomb, API13, tại thời điểm bài viết này được viết). Nó tìm thấy JDK 7 của tôi và được cài đặt đúng cách. Tương tự đối với ADT.
Nhưng tôi đã có một bất ngờ khi cố gắng biên dịch và chạy ứng dụng Hello Word Android. Khả năng tương thích được đặt thành Java 6 mà không có cách nào buộc nó thành Java 7:
Vì vậy, tôi đã Hello World làm việc, và cũng có các ứng dụng khác, phức tạp hơn và sử dụng SQLite
, Listview
, Sensor
và Camera
, nhưng điều này chỉ chứng minh rằng khả năng tương thích xử lý của Java 7 dường như được thực hiện tốt và làm việc với Android.
Vì vậy, có ai đó đã thử với Ant cũ tốt, để vượt qua giới hạn Eclipse đã thấy ở trên không?
Dù sao, SDK được thiết kế để được sử dụng với Java 5 hoặc 6, như được giải thích ở đây .
Chúng tôi có thể có một cái gì đó hoạt động với Java 7, nhưng nó sẽ hoạt động "tình cờ". Tòa nhà của DEX có thể hoạt động chính xác hoặc không, và một khi DEX được xây dựng, nó có thể hoạt động hoặc không. Điều này bởi vì sử dụng một JDK không đủ điều kiện cho kết quả không thể đoán trước theo định nghĩa.
Ngay cả khi ai đó đã thành công xây dựng một ứng dụng Android theo Java 7 đơn giản, điều này không đủ điều kiện cho JDK. Quá trình tương tự được áp dụng cho một ứng dụng khác có thể thất bại hoặc ứng dụng kết quả có thể có lỗi liên quan đến việc sử dụng JDK đó. Không được khuyến khích.
Đối với những người tham gia phát triển ứng dụng web, điều này giống hệt như việc triển khai một ứng dụng web được xây dựng theo Java 5 hoặc 6 trong một máy chủ ứng dụng chỉ đủ điều kiện cho Java 4 (ví dụ: Weblogic 8). Điều này có thể hoạt động, nhưng đây không phải là thứ có thể được khuyến nghị cho các mục đích khác ngoài việc thử.
Trích dẫn từ dalvikvm.com:
dx, được bao gồm trong SDK Android, chuyển đổi các tệp Lớp Java của các lớp Java được biên dịch bởi trình biên dịch Java thông thường thành định dạng tệp lớp khác (định dạng .dex)
Điều đó có nghĩa là, tệp nguồn .java không quan trọng, nó chỉ là mã byte. Class.
Theo như tôi biết, chỉ inv invocate được thêm vào mã byte JVM trong Java 7, phần còn lại tương thích với Java 6. Bản thân ngôn ngữ Java không sử dụng invokeocate . Các tính năng mới khác, như câu lệnh chuyển đổi sử dụng String s hoặc multi- Catch chỉ là đường tổng hợp và không yêu cầu thay đổi mã byte. Ví dụ, đa bắt chỉ sao chép chặn bắt cho từng ngoại lệ có thể.
Vấn đề duy nhất là các lớp mới được giới thiệu trong Java 7 bị thiếu trong Android, như AutoClosizable , vì vậy tôi không chắc liệu bạn có thể sử dụng tính năng thử tài nguyên (ai đó đã thử không?).
Bất kỳ ý kiến về điều đó? Tui bỏ lỡ điều gì vậy?
Kể từ Android SDK v15, cùng với Eclipse 3.7.1, Java 7 không được hỗ trợ để phát triển Android. Đặt khả năng tương thích nguồn thành 1.7 bắt buộc cài đặt khả năng tương thích tệp. Class được tạo thành 1.7, dẫn đến lỗi sau bởi trình biên dịch Android:
Android yêu cầu trình biên dịch tuân thủ cấp 5.0 hoặc 6.0. Tìm thấy '1.7' thay vào đó. Vui lòng sử dụng Công cụ Android> Sửa thuộc tính dự án.
Để mở rộng câu trả lời trên của @KennyTM, nếu bạn đang nhắm mục tiêu 4.0.3 trở lên ( minSdkVersion = 15 ), bạn có thể sử dụng các API ẩn bằng cách thêm một vài lớp vào SDK android.jar của mục tiêu.
Khi bạn thực hiện việc này, bạn có thể sử dụng tài nguyên thử với bất kỳ Đóng, cũng như triển khai AutoClosizable trong các lớp của riêng bạn.
Tôi đã tạo một zip chứa các nguồn và nhị phân của tất cả các lớp cần sửa đổi trong android.jar để cung cấp các API này. Bạn chỉ cần giải nén nó và thêm các nhị phân vào
android-sdk / platform / android-NN / android.jar của bạn
Bạn có thể tải xuống từ đây: http://db.tt/kLxAYWbr
Cũng đáng chú ý là, trong vài tháng qua, Elliott Hughes đã thực hiện một vài cam kết để cây Android: kết thúc AutoCloseable , thêm SafeVarargs , API khác nhau unhidden , cố định constructor bảo vệ Throwable của và hỗ trợ bổ sung cho phiên bản 51 tập tin lớp học trong dx . Vì vậy, cuối cùng cũng có một số tiến bộ đang diễn ra.
Chỉnh sửa (tháng 4 năm 2014):
Với việc phát hành SDK 19, không còn cần thiết phải vá android.jar bằng các API bổ sung.
Phương pháp tốt nhất để sử dụng tài nguyên dùng thử trong Android Studio cho một ứng dụng nhắm mục tiêu 4.0.3 trở lên ( minSdkVersion = 15 ) là thêm các mục sau compileOptions
vào 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 sẽ phàn nàn rằng không thể sử dụng tài nguyên thử với cấp API này, nhưng kinh nghiệm của tôi là nó có thể. Dự án sẽ xây dựng và chạy mà không gặp sự cố trên các thiết bị có 4.0.3 trở lên. Tôi đã trải nghiệm không có vấn đề với điều này, với một ứng dụng đã được cài đặt vào thiết bị 500k +.
Để bỏ qua cảnh báo này, hãy thêm những điều sau vào lint.xml
:
<issue id="NewApi">
<ignore regexp="Try-with-resources requires API level 19"/>
</issue>
Có vẻ như làm cho điều này hoạt động với kiến thuần là một chút bùn.
Nhưng nó đã làm việc cho tôi: http://www.informit.com/articles/article.aspx?p=1966024
custom_rules.xml
, xem câu trả lời của tôi ở đây: stackoverflow.com/a/24608415/194894
Để sử dụng các tính năng Java 7 trong xây dựng mã bởi hệ thống xây dựng dựa trên kiến của Android, chỉ cần đặt các mục sau trong custom_rules.xml
thư mục gốc dự án của bạn:
custom_rules.xml:
<project name="custom_android_rules">
<property name="java.target" value="1.7" />
<property name="java.source" value="1.7" />
</project>
Một số người có thể quan tâm đến dự án git này mà tôi đã tìm thấy, dường như cho phép chạy Java 7 trên Android. https://github.com/yareally/Java7-on-Android
Tuy nhiên, có quá nhiều rủi ro nếu tôi thêm điều này vào dự án hiện tại mà tôi làm việc. Vì vậy, tôi sẽ đợi cho đến khi Google chính thức hỗ trợ Java 7.