Cách sử dụng ThreeTenABP trong Android Project
Tôi đang hỏi câu hỏi này bởi vì tôi là người mới sử dụng Java và Android và tôi đã tìm kiếm hàng giờ để cố gắng tìm ra điều này. Câu trả lời đến từ sự kết hợp của các câu trả lời liên quan, vì vậy tôi nghĩ rằng tôi sẽ ghi lại những gì tôi học được cho bất kỳ ai khác có thể đang gặp khó khăn. Xem câu trả lời.
Tôi đang sử dụng Android Studio 2.1.2 và thiết lập Java của tôi như sau:
>java -version
> openjdk version "1.8.0_91"
> OpenJDK Runtime Environment (build 1.8.0_91-8u91-b14-3ubuntu1~15.10.1-b14)
> OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode)
Trả lời
Chú ý: Câu trả lời này, mặc dù đúng về mặt kỹ thuật, nhưng hiện đã lỗi thời
Hỗ trợ gỡ lỗi API Java 8+ hiện có sẵn thông qua Android Gradle Plugin 4.0.0+
(Xem thêm câu trả lời của Basil Bourque bên dưới )
Quá trình phát triển trên Thư viện ThreeTenABP sắp kết thúc. Vui lòng xem xét chuyển sang plugin Android Gradle 4.0, java.time. * Và tính năng gỡ rối thư viện cốt lõi của nó trong những tháng tới.
Để bật hỗ trợ cho các API ngôn ngữ này trên bất kỳ phiên bản nào của nền tảng Android, hãy cập nhật plugin Android lên 4.0.0 (hoặc cao hơn) và bao gồm thông tin sau trong tệp build.gradle của mô-đun của bạn:
android {
defaultConfig {
// Required when setting minSdkVersion to 20 or lower
multiDexEnabled true
}
compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 8
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.5'
}
Câu trả lời gốc
Khám phá đầu tiên: Tại sao bạn phải sử dụng ThreeTenABP thay vì java.time , ThreeTen-Backport hoặc thậm chí là Joda-Time
Đây là một phiên bản thực sự ngắn của QUÁ TRÌNH RẤT DÀI để xác định một tiêu chuẩn mới. Tất cả các gói này đều giống nhau: các thư viện cung cấp chức năng xử lý thời gian hiện đại, tốt cho Java. Sự khác biệt là nhỏ nhưng quan trọng.
Giải pháp rõ ràng nhất sẽ là sử dụng java.time
gói tích hợp, vì đây là cách tiêu chuẩn mới để xử lý thời gian và ngày tháng trong Java. Đây là một triển khai của JSR 310 , là một đề xuất tiêu chuẩn mới để xử lý thời gian dựa trên thư viện Joda-Time .
Tuy nhiên, java.time
đã được giới thiệu trong Java 8 . Android lên đến Marshmallow chạy trên Java 7 ("Android N" là phiên bản đầu tiên giới thiệu các tính năng của ngôn ngữ Java 8). Do đó, trừ khi bạn chỉ nhắm mục tiêu Android N Nougat trở lên, bạn không thể dựa vào các tính năng của ngôn ngữ Java 8 (tôi thực sự không chắc điều này là đúng 100%, nhưng đây là cách tôi hiểu). Như vậy java.time
là khỏi.
Tùy chọn tiếp theo có thể là Joda-Time , vì JSR 310 dựa trên Joda-Time. Tuy nhiên, như chỉ số ThreeTenABP chỉ ra, vì một số lý do, Joda-Time không phải là lựa chọn tốt nhất.
Tiếp theo là ThreeTen-Backport , hỗ trợ nhiều (nhưng không phải tất cả) java.time
chức năng của Java 8 sang Java 7. Điều này tốt cho hầu hết các trường hợp sử dụng, nhưng như đã chỉ ra trong readme ThreeTenABP , nó có vấn đề về hiệu suất với Android.
Vì vậy, lựa chọn cuối cùng và có vẻ đúng là ThreeTenABP .
Khám phá thứ hai: Xây dựng các công cụ và quản lý sự phụ thuộc
Vì việc biên dịch một chương trình - đặc biệt là một chương trình sử dụng nhiều thư viện bên ngoài - rất phức tạp, nên Java hầu như luôn sử dụng một "công cụ xây dựng" để quản lý quy trình. Make , Apache Ant , Apache Maven và Gradle đều là những công cụ xây dựng được sử dụng với các chương trình Java (xem bài đăng này để so sánh). Như đã lưu ý thêm, Gradle là công cụ xây dựng được lựa chọn cho các dự án Android.
Các công cụ xây dựng này bao gồm quản lý sự phụ thuộc. Apache Maven dường như là người đầu tiên bao gồm một kho lưu trữ gói tập trung. Maven đã giới thiệu Maven Central Repository , cho phép chức năng tương đương với php composer
với Packagist và Ruby gem
với rubygems.org. Nói cách khác, Maven Central Repository đối với Maven (và Gradle), Packagist là nhà soạn nhạc - một nguồn chắc chắn và an toàn cho các gói đã được phiên bản.
Khám phá thứ ba: Xử lý sự phụ thuộc Gradle trong các dự án Android
Điểm cao trong danh sách việc cần làm của tôi là đọc tài liệu Gradle ở đây , bao gồm cả sách điện tử miễn phí của họ. Nếu tôi đã đọc những tuần trước khi bắt đầu học Android, tôi chắc chắn đã biết rằng Gradle có thể sử dụng Kho lưu trữ trung tâm Maven để quản lý các phần phụ thuộc trong các Dự án Android. Hơn nữa, như chi tiết trong câu trả lời StackOverflow này , kể từ Android Studio 0.8.9, Gradle sử dụng Kho lưu trữ trung tâm Maven hoàn toàn thông qua JCenter của Bintray, có nghĩa là bạn không phải thực hiện thêm bất kỳ cấu hình nào để thiết lập kho lưu trữ - bạn chỉ cần liệt kê sự phụ thuộc.
Khám phá thứ tư: Sự phụ thuộc của dự án được liệt kê trong [dự án dir] /app/build.gradle
Một lần nữa, hiển nhiên đối với những người có kinh nghiệm sử dụng Gradle trong Java, nhưng tôi đã mất một lúc để tìm ra điều này. Nếu bạn thấy mọi người nói "Ồ, chỉ cần thêm compile 'this-or-that.jar'
" hoặc điều gì đó tương tự, hãy biết rằng đó compile
là một chỉ thị trong tệp build.gradle đó chỉ ra sự phụ thuộc vào thời gian biên dịch. Đây là trang Gradle chính thức về quản lý phụ thuộc.
Khám phá thứ năm: ThreeTenABP được quản lý bởi Jake Wharton, không phải bởi ThreeTen
Tuy nhiên, một vấn đề khác mà tôi đã dành quá nhiều thời gian để tìm ra. Nếu bạn tìm kiếm ThreeTen ở Maven Central, bạn sẽ chỉ thấy các gói cho threetenbp
chứ không phải threetenabp
. Nếu bạn truy cập github repo cho ThreeTenABP , bạn sẽ thấy compile 'this-or-that'
dòng khét tiếng đó trong phần Tải xuống của Readme.
Khi tôi lần đầu tiên nhấn repo github này, tôi không biết dòng biên dịch đó có nghĩa là gì và tôi đã cố gắng chạy nó trong thiết bị đầu cuối của mình (với một lỗi rõ ràng và có thể dự đoán được). Thất vọng, tôi đã không quay lại nó cho đến khi tôi tìm ra phần còn lại, và cuối cùng nhận ra rằng đó là một dòng Maven Repo trỏ đến com.jakewharton.threetenabp
repo, trái ngược với org.threeten
repo. Đó là lý do tại sao tôi nghĩ rằng gói ThreeTenABP không có trong Maven repo.
Tóm tắt: Làm cho nó hoạt động
Bây giờ tất cả có vẻ khá dễ dàng. Bạn có thể nhận các chức năng xử lý thời gian hiện đại trong một dự án Android bằng cách đảm bảo [project folder]/app/build.gradle
tệp của bạn có implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'
dòng trong dependencies
phần của nó :
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "me.ahuman.myapp"
minSdkVersion 11
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:appcompat-v7:23.4.0'
implementation 'com.android.support:design:23.4.0'
implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'
}
Cũng thêm cái này vào lớp Ứng dụng:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
AndroidThreeTen.init(this);
//...
}
}
Câu trả lời được chấp nhận bởi kael là đúng. Ngoài ra, tôi sẽ đề cập đến một số điều và cung cấp một sơ đồ về việc có được chức năng java.time .
java.time được tích hợp trong Android 26+
Nếu nhắm mục tiêu Android 26 trở lên, bạn sẽ thấy việc triển khai JSR 310 ( các lớp java.time ) đi kèm với Android. Không cần thêm ThreeTenABP .
Các API gần giống nhau
Chỉ cần làm rõ, ThreeTenABP cho Android là một bản chuyển thể của thư viện ThreeTen-Backport mang hầu hết các chức năng java.time cho Java 6 và Java 7 . Cổng phía sau này chia sẻ một API gần như giống hệt nhau với java.time .
Giả sử bây giờ bạn đang nhắm mục tiêu Android sớm hơn 26, vì vậy bạn sử dụng ThreeTenABP . Sau đó, cuối cùng bạn có thể ngừng hỗ trợ cho các phiên bản Android cũ hơn này, để sử dụng các lớp java.time đi kèm với Android. Khi điều đó xảy ra, bạn cần thực hiện một số thay đổi đối với cơ sở mã của mình ngoài (a) import
câu lệnh chuyển đổi và (b) thay đổi bất kỳ lệnh gọi nào bạn đã thực hiện org.threeten.bp.DateTimeUtils
để sử dụng các phương thức chuyển đổi mới đã được thêm vào các lớp ngày-giờ kế thừa cũ ( Date
, GregorianCalendar
) .
Quá trình chuyển đổi từ ThreeTenABP sang java.time sẽ diễn ra suôn sẻ và gần như không đau.
Khi nào sử dụng khuôn khổ nào
Đây là biểu đồ hiển thị ba khuôn khổ và cho biết khi nào sử dụng khuôn khổ nào trong các tình huống.
➥ Cập nhật: Android Gradle Plugin 4.0.0+ mang đến tùy chọn thứ 4 mới, gỡ lỗi API để cung cấp một tập hợp con của chức năng java.time không được tích hợp sẵn trong Android trước đó. Xem phần đầu của Câu trả lời chính của kael.
Giới thiệu về java.time
Khung java.time được tích hợp sẵn trong Java 8 trở lên. Những lớp học thay thế cái cũ phiền hà di sản lớp học ngày thời gian như java.util.Date
, Calendar
, & SimpleDateFormat
.
Để tìm hiểu thêm, hãy xem Hướng dẫn Oracle . Và tìm kiếm Stack Overflow để có nhiều ví dụ và giải thích. Đặc điểm kỹ thuật là JSR 310 .
Các Joda thời gian dự án, bây giờ trong chế độ bảo trì , khuyên chuyển đổi sang các java.time lớp.
Bạn có thể trao đổi các đối tượng java.time trực tiếp với cơ sở dữ liệu của mình. Sử dụng trình điều khiển JDBC tương thích với JDBC 4.2 trở lên. Không cần chuỗi, không cần java.sql.*
lớp. Hibernate 5 & JPA 2.2 hỗ trợ java.time .
Lấy các lớp java.time ở đâu?
- Java SE 8 , Java SE 9 , Java SE 10 , Java SE 11 và mới hơn - Một phần của API Java tiêu chuẩn với một triển khai đi kèm.
- Java 9 bổ sung một số tính năng nhỏ và các bản sửa lỗi.
- Java SE 6 và Java SE 7
- Hầu hết các chức năng java.time được chuyển ngược sang Java 6 & 7 trong ThreeTen-Backport .
- Android
- Các phiên bản triển khai gói Android mới hơn của các lớp java.time .
- Đối với Android trước đó (<26), các ThreeTenABP dự án thích nghi ThreeTen-backport (nêu trên). Xem Cách sử dụng ThreeTenABP… .
Thêm phần sau vào tệp gradle bản dựng của bạn trong Android Studio.
implementation 'com.jakewharton.threetenabp:threetenabp:1.2.1'
Tạo lớp Ứng dụng và khởi tạo nó như sau:
class App : Application() {
override fun onCreate() {
super.onCreate()
AndroidThreeTen.init(this)
}
}