Bạn đã từng nghĩ.. “Điều mà thực sự tôi cần là một cách để kết nối Swift với Java” nhưng có nhiều ứng dụng sử dụng như sau:
- Làm cho các công nghệ Java như JDBC có sẵn cho các ứng dụng macOS.
- Đưa giao diện người dùng có thể di động vào ứng dụng Swift trên Linux bằng cách sử dụng Swing.
- Đưa ngôn ngữ logic kinh doanh được viết bằng Swift có sẵn cho các ứng dụng Android.
SwiftJava là một công cụ tạo mã Swift cùng với một framework nhỏ của mã hỗ trợ được viết bằng phiên bản Xcode beta6 của Swift 3.0. Điểm khởi đầu là bài diễn thuyết Cross Platform Swift của Boris Bügling. Công cụ tạo mã này lấy một lớp, giao diện hoặc gói Java và tạo mã Swift tương ứng để giao tiếp với các phương thức Java tương ứng sử dụng Java Native Interface “JNI”. Các phương thức này được tạo ra trên lớp Swift tương ứng và có dạng như sau:
Ở macOS, công cụ này đã được sử dụng để tạo ra các framework kết nối các gói java.lang, java.util, java.sql, java.awt và javax.swing cùng với các bổ sung cụ thể của Apple trong gói com.apple. Điều này giúp các api Java có sẵn với chức năng tự động hoàn thiện trong trình soạn thảo mã nguồn Xcode. Ứng dụng cuối cùng có thể là một “.app” hoặc một tiện ích dòng lệnh có thể di động trên Linux bằng Swift Package Manager. Đối với Android, công cụ tạo mã có thể tạo mã JNI cho một cặp giao diện từ Java sang Swift và từ Swift sang Java, giúp nhà phát triển tiết kiệm công sức stubbing thủ công tốn nhiều thời gian.
Để sử dụng công cụ này, sao chép dự án này bằng lệnh sau:
git clone <đường dẫn dự án>
Dự án này chứa các framework Java được tạo trước, một ứng dụng macOS ví dụ sử dụng JDBC và một dự án dòng lệnh với nguồn AWT và Swing đa dạng. Phát triển trong Xcode sử dụng việc “JavaVM” cổ điển cần tải xuống JVM của Apple từ:
https://support.apple.com/kb/dl1572?locale=en_US
Việc phát triển trong Xcode với Oracle JVM phức tạp hơn một chút. Dường như JNI_CreateJavaVM sinh ra lỗi SIGSEGV như một phần của hoạt động bình thường và nó bị nắm giữ bằng một bộ giám sát tín hiệu để tiếp tục ở dòng lệnh. Rất tiếc, điều này bị lỗi bởi trình gỡ lỗi lldb của Xcode và nó đình chỉ và sẽ không tiếp tục cho đến khi bạn nhập pr h -s false SIGSEGV vào bảng điều khiển gỡ lỗi mỗi khi chạy chương trình. Lựa chọn khác là không sử dụng trình gỡ lỗi trong chế độ này.
Lạ lùng, với AWT và Swing trên macOS, JVM cần được tạo ra trên luồng chính trong khi mã thiết lập cần phải nằm ngoài luồng chính để hoạt động được sử dụng luân lưu runloop tự động của AWT. Sử dụng các phương thức JNI.background và JNI.run để thực hiện điều này một cách di động.
Xem thêm : Mẹo chia sẻ tài liệu làm việc bằng file Word với nhiều người
Khi sử dụng Swift package manager để xây dựng mã từ dòng lệnh, cài đặt Oracle JDK mới nhất và định vị thư mục chứa file libjvm.so hoặc .dylib trong jre. Sử dụng thư mục examples để xây dựng bằng các lệnh sau:
cd examples
swift build
Nguồn Swing trong “examples/Sources” cho thấy cách nhận sự kiện và tạo lớp Java con để có một số phương thức như java.awt.Canvas.paint() được thực hiện bằng Swift. Sẽ có thêm thông tin về điều này sau đây.
Phát triển Android
Đối với Android, hãy tham khảo phiên bản sửa đổi của các ví dụ swift-android-samples và ứng dụng hệ thống gradle liên quan từ Android Toochain. Việc này hoạt động trên macOS hoặc Ubuntu 16.04 và yêu cầu thiết bị Lollipop (api 21) hoặc cao hơn. Thông tin chi tiết hơn và ngữ cảnh có sẵn trong README Swift cho Android và hướng dẫn toàn diện này, nhưng hy vọng các tập lệnh trong plugin gradle được sửa đổi sẽ giúp giảm rất nhiều sự mất công.
Sau khi bạn có một bộ công cụ và chạy tập lệnh setup.sh, bạn có thể gõ các lệnh sau:
./goforit.sh
Đối với một ứng dụng mới, hãy xác định hai giao diện Java, một để gửi tin nhắn từ Java đến Swift với tên kết thúc bằng “Listener” và một để gửi tin nhắn ngược lại từ Swift đến Java. Sau đó, sử dụng ./genswift.sh từ dự án này để tạo mã kết nối Swift:
./genswift.sh
Điều này sẽ tạo ra các lớp Swift và mã nguồn Java thứ ba src/org/swiftjava/your_package/YourAppProxy.java cũng cần được bao gồm vào dự án của bạn. Hãy tham khảo tập lệnh genhello.sh và dự án “swift-android-samples/swifthello” để biết chi tiết. Nguồn “swift-android-samples/swifthello/src/main/swift/Sources/main.swift” cho thấy cách thiết lập này với một phương pháp native được gọi từ hoạt động chính.
Forward, Runnable, Listener, Adapter, subclass responsibility và Base classes.
Đối với mỗi giao diện Java, công cụ tạo mã sẽ tạo ra một Swift Protocol cùng với một ProtocolForward class, một phiên bản của nó tuân theo giao diện và có thể được sử dụng để gửi tin nhắn từ các đối tượng Java tuân theo giao diện/protocol.
Đối với giao diện Runnable được sử dụng trong luồng thì cần phải có khả năng ngược lại, trong đó mã Java có thể gọi Swift code. Điều này được thực hiện bằng cách sử dụng một lớp proxy Java có con trỏ được liên kết với đối tượng Swift tương ứng và một triển khai “native” của phương thức “run()” gọi qua Swift. Ở phía Swift, điều này có thể được truy cập thông qua lớp “RunnableBase” có thể được kế thừa để cung cấp một triển khai Swift của phương thức “run()” có thể được gọi từ Java.
Phương pháp này cũng được áp dụng cho xử lý sự kiện và tất cả các giao diện có tên kết thúc bằng “Listener”, “Manager” hoặc “Handler” cũng có các lớp “Base” được tạo ra để kế thừa cùng với các lớp phụ Java Proxy. Trên macOS và Linux, các lớp này được biên dịch thành một file jar ~/swiftjava.jar theo lệnh genjar.sh để có thể hoạt động.
Xem thêm : Gợi ý 7 cuốn sách JavaScript các lập trình viên nên đọc
Bất kỳ giao diện/protocol nào từ giao diện Java có thể được thêm vào một lớp để cho phép nó được truyền đến Java nếu tên của nó kết thúc bằng Listener. Việc triển khai có chút phức tạp nhưng không có một gánh nặng đáng kể. các struct cũng có thể được truy cập từ Java bằng cách này nhưng đối tượng sẽ không được truy cập trực tiếp, tức là một bản sao của struct sẽ được tạo ra.
Một số xử lý sự kiện cũng được thực hiện bằng cách kế thừa các lớp cụ thể có tên kết thúc bằng “Adapter”. Lớp “Base” Swift được sửa đổi một chút và các Java Proxy cũng được tạo ra cho điều này. Các lớp khác có các phương thức được cho là chịu trách nhiệm của các lớp con như java.awt.Canvas.paint(). Danh sách các phương thức này cần được duy trì trong công cụ tạo mã, không may là một lớp đáy và Proxy được tạo ra cho lớp cụ thể có thể được kế thừa.
Vì các lớp “Base” này không thể đóng các biến trong chương trình của bạn, bạn có thể tạo một phương thức khởi tạo để chụp chúng. Có một số việc chuẩn cần được thực hiện. Tạo một đối tượng cơ sở “Base” và gán đối tượng javaObject của nó cho đối tượng javaObject của lớp của bạn. Do việc sử dụng kiểu thông qua generics, bạn cũng sẽ được nhắc nhở để cung cấp một triển khai null của khởi tạo “required”.
Xem ví dụ mã Swing để biết thêm thông tin chi tiết.
The MIT License (MIT) Bản quyền (c) 2016, John Holdsworth
Được cấp phép theo giấy phép MIT (MIT) Được cấp miễn phí cho bất kỳ ai nhận được bản sao của phần mềm này và các tệp tài liệu liên quan (phần mềm), để giao dịch trong Phần mềm mà không bị hạn chế, bao gồm mà không giới hạn vào quyền sử dụng, sao chép, sửa đổi, hợp nhất, xuất bản, phân phối, cấp phép lại và/hoặc bán bản sao của Phần mềm và cho phép những người nhận được Phần mềm làm như vậy, miễn là các điều kiện sau được tuân thủ:
Thông báo bản quyền trên và thông báo giấy phép này phải được bao gồm trong tất cả các bản sao hoặc các phần quan trọng của Phần mềm.
PHẦN MỀM ĐƯỢC CUNG CẤP “TƯƠNG TỰ NHƯ NÓ”, KHÔNG CÓ BẢO ĐẢM BẤT KỲ LOẠI NÀO, BAO GỒM NHƯNG KHÔNG GIỚI HẠN ĐẾN CÁC BẢO ĐẢM VỀ ĐỘ CHÍNH XÁC, ĐÁNG TIN CẬY, THÍCH HỢP CHO MỤC ĐÍCH CỤ THỂ VÀ PHỔ BIẾN. TRONG BẤT KỲ TRƯỜNG HỢP NÀO, TÁC GIẢ HOẶC CHỦ SỞ HỮU BẢN QUYỀN SỞ HỮU KHÔNG CHỊU TRÁCH NHIỆM ĐỐI VỚI BẤT KỲ YÊU CẦU, THIỆT HẠI HOẶC TRÁCH NHIỆM KHÁC, DỮ LIỆU TRONG MỘT HÀNH ĐỘNG HỢP ĐỒNG, NGUYỄN TẮC HOẶC KHÁC CÓ NGUỒN GỐC TỪ, NGOÀI HOẶC TRONG KẾT NỐI VỚI PHẦN MỀM HOẶC VIỆC SỬ DỤNG HOẶC CÁC HỢP ĐỒNG KHÁC VỚI PHẦN MỀM.
Giấy phép này không áp dụng cho mã được tạo ra từ phân phối của Apple của JVM mà được cung cấp theo các quy định về “Sử dụng hợp lý” và việc sử dụng cuối cùng của bạn cuối cùng phụ thuộc vào Hợp đồng Cấp phép gốc.
Nguồn: https://laptrinhc.edu.vn
Danh mục: Tài liệu IT