2009-05-13 32 views
13

Tôi đang cố gắng để mã một ứng dụng chạy nền tảng java khác nhau như J2SE, J2ME, Android, vv Tôi đã biết rằng tôi sẽ phải viết lại hầu hết các Giao diện người dùng cho mỗi nền tảng, nhưng muốn sử dụng lại logic lõi.Làm thế nào để đối phó với các lớp phổ biến nhất bị thiếu trên J2ME

Giữ di động lõi này bao gồm ba nhược điểm mà tôi biết:

  1. Giữ cho cái cũ Java 1,4 cú pháp, không sử dụng bất kỳ tính năng ngôn ngữ tốt đẹp của Java 5.0
  2. chỉ sử dụng bên ngoài thư viện được biết là hoạt động trên các nền tảng đó (nghĩa là: không sử dụng JNI và không có phụ thuộc vào các libs khác vi phạm quy tắc này)
  3. chỉ sử dụng các lớp có mặt trên tất cả những nền tảng

Tôi biết cách để vượt qua (1): mã trong 5,0 phong cách và tự động chuyển đổi nó đến 1,4 (retroweaver - đã không thử nó, nhưng có vẻ ok).

Tôi nghĩ rằng (2) là sự cố mà tôi chỉ phải chấp nhận.

Bây giờ tôi muốn biết nền tảng tốt nhất là gì cho (3), đặc biệt là các lớp sưu tập mà tôi nhớ nhiều nhất. Tôi có thể nghĩ đến những:

  • Hầu hết các lập trình viên tôi biết chỉ không sử dụng Set, Map, List, vv và dự phòng để Vector và Mảng đồng bằng. Tôi nghĩ rằng điều này làm cho mã xấu xí ngay từ đầu. Nhưng tôi cũng biết rằng lựa chọn đúng giữa TreeSet/Hashset hoặc LinkedList/ArrayList rất quan trọng đối với hiệu suất và luôn sử dụng Vector và mảng không thể đúng.
  • Tôi có thể viết mã các triển khai của riêng mình cho các lớp đó. Điều này dường như đang phát minh ra bánh xe, và tôi nghĩ rằng tôi không thể làm điều đó tốt như những người khác đã làm.
  • Vì Java là mã nguồn mở, tôi có thể lấy mã nguồn của khung công tác Bộ sưu tập J2SE và đưa vào ứng dụng của tôi khi xây dựng cho J2ME. Tôi không biết nếu đây là một ý tưởng tốt, mặc dù. Có lẽ có lý do chính đáng để không làm điều này.
  • Có thể đã có các thư viện ở đó, xây dựng lại các tính năng quan trọng nhất của khung bộ sưu tập, nhưng được tối ưu hóa cho các hệ thống cấp thấp, có lẽ không thực hiện chức năng được sử dụng thường xuyên. Bạn có biết gì không?

Cảm ơn câu trả lời và ý kiến ​​của bạn!

Chỉnh sửa: Cuối cùng tôi đã tìm thấy một giải pháp phức tạp nhưng thú vị bằng cách cung cấp câu trả lời của riêng tôi và chấp nhận nó, giải pháp sẽ hiển thị ở trên cùng. Nhưng ngược lại, câu trả lời của tôi vẫn ở dưới cùng.

Trả lời

12

Đã một thời gian kể từ khi tôi hỏi câu hỏi này, và tôi trong khi kể từ khi tôi tìm thấy một giải pháp tốt đẹp, làm việc cho vấn đề này, nhưng tôi đã có từ forgotton để cho bạn biết.

Trọng tâm chính của tôi là Khung sưu tập Java, là một phần của gói java.util.

Cuối cùng tôi đã lấy mã nguồn của Suns Java 6.0 và sao chép tất cả các lớp thuộc khuôn khổ Bộ sưu tập vào một dự án của riêng tôi. Đây là một dự án Java 6.0, nhưng tôi đã sử dụng các jars từ J2ME như classpath. Hầu hết các lớp mà tôi đã sao chép đều phụ thuộc vào các lớp J2SE khác, do đó, có những phụ thuộc bị hỏng. Dù sao, nó đã được khá dễ dàng để cắt giảm những depensencies bằng cách rời khỏi tất cả mọi thứ mà đề với serialization (mà không phải là một ưu tiên cho tôi) và một số điều chỉnh nhỏ.

Tôi đã biên dịch toàn bộ nội dung bằng trình biên dịch Java 6 và trình truyền lại được sử dụng để chuyển kết quả bytecode quay lại Java 1.2.

Sự cố tiếp theo là tên gói, vì bạn không thể phân phối các lớp từ java.util bằng ứng dụng J2ME và tải chúng - trình tải lớp bootstrap sẽ không xem trong tệp jar ứng dụng, các trình khởi động khác không được phép tải một cái gì đó với tên gói đó, và trên J2ME bạn không thể định nghĩa các trình nạp lớp tùy chỉnh. Retrotranslator không chỉ chuyển đổi bytecode, nó còn giúp thay đổi các tham chiếu tên trong bytecode hiện tại. Tôi phải di chuyển và đổi tên tất cả các lớp trong dự án của mình, ví dụ:java.util.TreeMap đã trở thành my.company.backport.java.util.TreeMap_. Tôi đã không thể viết ứng dụng J2ME thực tế trong dự án Java 6.0 thứ hai tham chiếu đến thông thường java.util.TreeMap, bằng cách sử dụng cú pháp chung để tạo các bộ sưu tập loại an toàn, biên dịch ứng dụng đó sang mã Java 6.0 byte và chạy nó thông qua bộ chuyển mã retrotranslator để tạo mã Java 1.2 hiện tham chiếu my.company.backport.java.util.TreeMap_. Lưu ý rằng TreeMap chỉ là một ví dụ, nó thực sự hoạt động cho toàn bộ khuôn khổ bộ sưu tập và ngay cả đối với các J2SE Jars bên thứ ba tham chiếu đến khung công tác đó.

Ứng dụng kết quả có thể được đóng gói dưới dạng tệp jar và jad và chạy tốt trên cả trình giả lập J2ME và thiết bị thực (được thử nghiệm trên Sony Ericsson W880i). Toàn bộ quá trình có vẻ khá phức tạp, nhưng kể từ khi tôi sử dụng Ant để xây dựng tự động hóa, và dù sao tôi cũng cần truyền lại, chỉ có một chi phí một lần để thiết lập backport khung công tác thu thập.

Như đã nói ở trên, tôi đã thực hiện điều này gần một năm trước và viết chủ yếu từ đầu của tôi, vì vậy tôi hy vọng không có lỗi trong đó. Nếu bạn quan tâm đến nhiều chi tiết hơn, hãy để lại cho tôi một bình luận. Tôi có một vài trang tài liệu của Đức về quy trình đó, mà tôi có thể cung cấp nếu có bất kỳ nhu cầu nào.

+0

Bạn có sẵn sàng cung cấp backport của bạn về khung bộ sưu tập? Retrotranslator là tuyệt vời, nhưng tôi đã phải viết backports của riêng tôi chỉ để có được autoboxing làm việc. – Ralf

+0

Bất kỳ cơ hội nào bạn có thể chia sẻ backport này? – domino

2

Để trả lời một phần câu hỏi của bạn, một thư viện bộ sưu tập khác sẽ là Javolution có thể được xây dựng cho j2me.

+0

Xin chào, cảm ơn, có vẻ thú vị. Bạn có biết nếu tôi phải sử dụng toàn bộ công cụ Javolution (chắc chắn là tốt đẹp, nhưng có thể đi kèm với các vấn đề/nhược điểm khác) nếu tôi có thể sử dụng bộ sưu tập từ Javolution của riêng mình? –

+0

Tôi không chắc chắn, tôi chưa bao giờ sử dụng nó như thế nên tôi không thể nói với bạn. – BenM

+0

Tôi cũng tự hỏi về điều này, nhưng từ kinh nghiệm của tôi trong việc cố gắng cô lập chỉ là một vài lớp sưu tập, dường như có rất nhiều phụ thuộc lẫn nhau trong chính thư viện. –

3

Chúng tôi phải đối mặt chính xác với tình huống này khi phát triển zxing.Nếu J2ME nằm trong danh sách các mục tiêu của bạn, đây là yếu tố hạn chế của bạn cho đến nay. Chúng tôi đã nhắm mục tiêu MIDP 2.0/CLDC 1.1. Nếu bạn có một yêu cầu tương tự, bạn cần phải gắn bó với Java 1.2. Java 1.4 tính năng ngôn ngữ chắc chắn không có mặt (như khẳng định) và nói chung bạn sẽ không tìm thấy bất cứ điều gì sau 1,2 trong J2ME.

Chúng tôi không sử dụng thư viện bên ngoài, nhưng bạn có thể gói chúng vào tệp .jar được triển khai của mình mà không gặp phải vấn đề gì. Nó sẽ làm cho kết quả lớn hơn .jar, và đó có thể là một vấn đề. (Sau đó, bạn có thể thử các trình tối ưu hóa/thu nhỏ như ProGuard để giảm thiểu điều đó.)

Tôi đã kết thúc việc thực hiện một cái gì đó như Collections.sort() và Comparator vì chúng tôi cần chúng và chúng không có trong J2ME. Vì vậy, yeah bạn có thể xem xét làm điều này trong trường hợp, mặc dù chỉ khi cần thiết.

Chúng tôi đã sử dụng Vector và Hashtable và mảng vì không có lựa chọn nào khác, thực sự, trong J2ME. Tôi sẽ chỉ sử dụng chúng trừ khi bạn có lý do để không, và đó sẽ là hiệu suất tôi đoán. Về lý thuyết các nhà sản xuất JVM đã tối ưu hóa việc triển khai nhưng điều đó không có nghĩa là bạn không thể làm tốt hơn ... Tôi đoán tôi sẽ ngạc nhiên nếu nó đáng giá trong phần lớn các trường hợp. Chỉ cần chắc chắn rằng bạn thực sự cần phải làm điều này trước khi đưa vào nỗ lực.

+2

Sửa đổi về Java ME: CLDC sử dụng mã phiên bản 1.3, CDC sử dụng 1.4. Tôi không thể nhớ ngay bây giờ những thay đổi là giữa 1,2 và 1,3 nhưng CLDC sử dụng 1,3. – Malcolm

+1

Không có thay đổi ngôn ngữ từ 1,2 đến 1,3, chỉ thay đổi API và JVM. Tất nhiên CLDC có một tập con API và JVM hoàn toàn khác. Vì vậy, tôi đoán hoặc là về đúng, nhưng tôi tưởng tượng tuyên bố của bạn là đúng-er cho những ngày có liên quan. –

+2

Wow, không nghĩ rằng một bình luận cũ như vậy có thể được trả lời. Nhận xét của tôi thực sự được hỗ trợ bởi đặc tả CLDC, trong đó nói rằng "CLDC hỗ trợ một số lớp đã được bắt nguồn từ Java Standard Edition, phiên bản 1.3.1". Tôi đồng ý mặc dù ngôn ngữ không thay đổi giữa các phiên bản Java 1.2 và 1.3 (JLS thứ hai áp dụng cho cả hai), và vì CLDC là một tập con rất hạn chế, không có sự khác biệt khủng khiếp. – Malcolm

13

J2ME là tàn bạo, và bạn sẽ phải từ chức bản thân để làm mà không có một số điểm yếu của các nền tảng khác. Làm quen với Hashtable và Vector, và viết các trình bao bọc của riêng bạn lên trên. Ngoài ra, đừng mắc sai lầm khi giả định rằng J2ME là tiêu chuẩn, vì mỗi JVM của nhà sản xuất có thể làm mọi thứ theo những cách khác nhau sâu sắc. Tôi sẽ không lo lắng nhiều về hiệu suất ban đầu, như chỉ nhận được đúng đắn trên J2ME là đủ của một thách thức. Có thể viết một ứng dụng chạy trên J2ME, J2SE và Android, như tôi đã làm, nhưng phải mất rất nhiều công sức. Một gợi ý mà tôi muốn có là bạn viết cốt lõi của logic ứng dụng của bạn và giữ nó chặt chẽ với java.lang, java.util và java.io. Bất cứ nơi nào bạn định làm gì đó có thể tương tác với nền tảng, chẳng hạn như hệ thống tệp hoặc mạng, bạn có thể tạo giao diện mà mã ứng dụng cốt lõi của bạn tương tác với nhau, rằng bạn có các triển khai khác nhau cho các môi trường khác nhau. Ví dụ, bạn có thể có một giao diện kết thúc các công cụ HTTP và sử dụng javax.microedition.io.HttpConnection với J2ME và java.net.HttpURLConnection trên Android. Đó là một nỗi đau, nhưng nếu bạn muốn duy trì một ứng dụng chạy trên cả ba môi trường đó, nó có thể giúp bạn ở đó. Chúc may mắn.

Các vấn đề liên quan