• Thứ Tư, 20/07/2005 10:04 (GMT+7)

    MIDP 2.0 có gì mới?

    Mobile Information Device Profile (MIDP) cung cấp thư viện API chuẩn để phát triển ứng dụng di động Java. So với phiên bản 1.0, MIDP 2.0 có nhiều cải tiến và bổ sung hấp dẫn cho các nhà phát triển.

    An toàn cho kết nối mạng

    Giao thức duy nhất mà MIDP 1.0 yêu cầu là HTTP. MIDP 2.0 thêm HTTPS, là giao thức HTTP trên SSL (Secure Socket Layer) - giao thức mã hóa dữ liệu truyền trên mạng. Mặc dù nhiều thiết bị MIDP 1.0 có hỗ trợ HTTPS nhưng nhà phát triển không có cơ sở chắc chắn. MIDP 2.0 cung cấp cơ sở chắc chắn, nhất quán hơn để phát triển ứng dụng di động có liên quan đến thanh toán và thông tin nhạy cảm.

    HTTPS được hỗ trợ thông qua khung kết nối mạng chuẩn (Generic Connection Framework) của CLDC trong gói javax.microedition.io. Chẳng hạn, javax.microedition.io.HttpsConnections là một trong nhiều interface mới hỗ trợ bảo mật mạng, lớp javax.microedition.io.SecurityInfo chứa thông tin về kết nối bảo mật, và lớp javax.microedition.pki.Certificate biểu diễn một chứng thực được mã hóa...

    Vì tính nhạy cảm của kết nối mạng, đặc tả MIDP 2.0 đưa ra các khái niệm đoạn mã an toàn, không an toàn và các quyền hạn (permisson). Các đoạn mã không an toàn không thể tạo kết nối tùy ý; nó cần phải nhận được sự cho phép từ người dùng. Các đoạn mã có thể được chỉ định là an toàn nếu nhà phát triển chứng thực số cho nó và thiết bị của người dùng có thể kiểm tra chứng thực số đó.

    Cơ chế “hỏi xin” và “cho phép” cụ thể sẽ tùy thuộc vào các chính sách bảo mật của thiết bị và theo định nghĩa của người dùng. Ví dụ, hãy xét một game kết nối đến server để duy trì danh sách bảng điểm (high-score). Nếu game không được chứng thực, hoặc được chứng thực bởi một nguồn mà thiết bị không nhận ra được thì chương trình game bị xem là không an toàn. Khi game cố tạo kết nối đến server lưu giữ high-score, thiết bị MIDP 2.0 sẽ từ chối hành động này (bằng một SecurityException lúc thực thi) hoặc yêu cầu người dùng xác nhận cho phép hay từ chối kết nối mạng. Nếu game đã được chứng thực và thiết bị kiểm tra được, thì chương trình game sẽ được xác định là an toàn và được phép tạo kết nối mạng.

    Một số mục đặc biệt trong tập tin manifest sẽ cho phép bộ MIDlet suite chỉ định những quyền hạn nào mà nó cần để có thể chạy chương trình một cách thông suốt. Đặc tả MIDP 2.0 định nghĩa các khai báo quyền hạn cho nhiều kiểu kết nối mạng. Đây là kiến trúc có khả năng mở rộng, và các gói tùy chọn làm việc với các API nhạy cảm sẽ định nghĩa thêm các kiểu quyền hạn.

    Để xem danh sách chi tiết các quyền hạn và chứng thực mã, hãy đọc thêm tài liệu Security for MIDP Applications và Trusted MIDlet Suites Using X.509 PKI trong đặc tả MIDP 2.0 (http://jcp.org/aboutJava/communityprocess/final/jsr118/index.html).

    Multimedia

    Một trong những điểm hấp dẫn nhất của MIDP 2.0 là thư viện media. Thư viện này là một tập con của Mobile Media API (MMAPI) hỗ trợ audio.

    Giờ đây, bạn có thể tạo ra âm thanh (tone) một cách đơn giản dùng phương thức playTone() trong lớp javax.microedition.media.Manager. Tất cả những gì bạn cần làm là cung cấp một giá trị nốt (ví dụ 60 là nốt Đô (C) trung), trường độ (thời gian phát một nốt, tính bằng mili giây) và cao độ (0 là im lặng, 100 là cao nhất). Phương thức này đưa ra một MediaException nếu không phát được âm thanh. Đoạn chương trình sau phát một nốt đô trung trong nửa giây ở mức âm lượng cao nhất.

    try {
    Manager.playTone(60, 500, 100);
    }
    catch (MediaException me) {
    // Handle the exception.
    }

    Thư viện này cũng hỗ trợ phát nhiều chuỗi âm thanh. Bạn cần phải đi sâu hơn một chút vào thư viện này, sử dụng lớp giao diện javax.microedition.medi.control.ToneControl. Tài liệu JavaDoc của ToneControl có một ví dụ đơn giản minh họa kỹ thuật này.

    Thư viện API media của MIDP 2.0 còn hỗ trợ phát một số tập tin âm thanh. Thiết bị phải có khả năng phát tập tin WAV và một số định dạng audio khác.

    Đoạn chương trình để phát tập tin audio đơn giản một cách đáng ngạc nhiên. Đầu tiên bạn cần lấy một thể hiện Player cho dữ liệu audio, sau đó bạn chỉ cần thiết lập cho Player chạy. Đoạn chương trình sau thể hiện cách phát một tập tin WAV được lưu trong tập tin tài nguyên của MIDlet:

    InputStream in =
    getClass().getResourceAsStream(“/signs_m.wav”);
    Player p = Manager.createPlayer(in, “audio/x-wav”);
    p.start();

    Cải tiến trong Form

    Nhiều cải tiến đã được thêm vào gói javax.microedition.lcdui trong MIDP 2.0, nhưng thay đổi lớn nhất (ngoài thư viện Game API) là trong Form và Item.

    Đầu tiên, bố trí (layout) của Form phức tạp hơn nhiều so với MIDP 1.0. Tài liệu JavaDoc của Form mô tả chi tiết thuật toán layout mới. Nói một cách ngắn gọn, các item được sắp đặt từ trái qua phải trong cùng hàng và được xếp từ trên xuống dưới giống như cách sắp đặt trong đoạn văn. Bạn có thể chỉnh sửa layout này, nhưng nên nhớ rằng chỉ sử dụng những layout mà thiết bị hỗ trợ. Cuối cùng, chính thiết bị sẽ quyết định chính xác vị trí cũng như kích thước thể hiện của các Item.

    Các Item (thành phần trong Form) giờ đây có thêm kích thước nhỏ nhất và kích thước ưa thích (preferred), các kích thước này có thể được thiết lập bởi ứng dụng. Nếu bạn không xác định những kích thước này thì chính thiết bị sẽ tính toán chúng. Lớp Item cũng chứa các hằng số layout mà trước đây chỉ có trong lớp ImageItem. Bạn có thể xác định layout theo hàng ngang, hàng dọc, đầu dòng, hoặc cuối dòng và các ràng buộc khác.

    Ngoài tính năng layout mới, Form còn có thêm các Item mới, ví dụ Spacer thể hiện một khoảng trống, bạn có thể sử dụng nó để tinh chỉnh layout của Form. Item ChoiceGroup có thêm kiểu, POPUP. Một ChoiceGroup kiểu POPUP dùng để tạo một combo box. Nó hiển thị lựa chọn hiện tại và một dấu hiệu (một hình tam giác chỉ xuống chẳng hạn) để thể hiện là còn nhiều lựa chọn khác, khi lựa chọn hoặc kích hoạt nó thì toàn bộ danh sách các lựa chọn sẽ xuất hiện. Alert bây giờ có thêm các lệnh cho phép lập trình viên sử dụng màn hình này để đặt câu hỏi với người dùng.

    MIDP 2.0 cũng mở rộng việc quản lý lệnh (command). Trong MIDP 1.0, các command được thêm vào các đối tượng Displayable và một đối tượng lắng nghe (Listener) sẽ nhận tất cả các sự kiện command. MIDP 2.0 mở rộng mô hình này bằng cách cho phép bạn thêm các command vào từng Item. Từ quan điểm của người lập trình, điều này tạo nên sự linh động. Thiết bị sẽ có thêm một chút khó khăn khi tính toán làm cách nào để hiển thị các command một cách thích hợp. Việc đưa command vào Item cũng tương tự như đưa command vào đối tượng Displayable. Chỉ cần chuyển một command cho phương thức addItemCommand() của Item. Để đăng ký một bộ lắng nghe, hãy kế thừa lớp giao diện ItemCommandListener và đăng ký bộ lắng nghe với phương thức setItemCommandListener() của Item.

    Các Item cũng có một command mặc định (default command), command này có thể được triệu gọi thông qua một thể hiện trên giao diện người dùng. Thể hiện này đa dạng tùy theo thiết bị; nó có thể là một nút nhấn đặc biệt hoặc một thể hiện bút vẽ (stylus). Bạn có thể thiết lập command mặc định bằng phương thức setDefaultCommand() của lớp Item.

    Một trong những điểm mới trong Form là CustomItem, một lớp Item tuỳ biến. Với khái niệm tương tự như Canvas, CustomItem cho phép bạn tự vẽ và đáp ứng lại những sự kiện giao diện đặc biệt. Tạo một Item tuỳ biến chỉ là vấn đề kế thừa lớp con CustomItem và kế thừa các phương thức abstract của nó. Ví dụ sau đây tạo một nút bật tắt với đoạn mã tối thiểu:

    import javax.microedition.lcdui.*;

    public class DiamondItem

    extends CustomItem {

    private boolean mState;

    public DiamondItem(String title) {

    super(title);

    mState = false;

    }

    public void toggle() {

    mState = !mState;

    repaint();

    }

    // CustomItem abstract methods.

    public int getMinContentWidth() { return 80; }

    public int getMinContentHeight() { return 40; }

    public int getPrefContentWidth(int width) {

    return getMinContentWidth();

    }

    public int getPrefContentHeight(int height) {

    return getMinContentHeight();

    }

    public void paint(Graphics g, int w, int h) {

    g.drawRect(0, 0, w - 1, h - 1);

    int stepx = 8, stepy = 16;

    for (int y = 0; y < h; y += stepy) {

    for (int x = 0; x < w; x += stepx) {

    g.drawLine(x, y, x + stepx, y + stepy);

    g.drawLine(x, y + stepy, x + stepx, y);

    if (mState == true) {

    int midx = x + stepx / 2;

    int midy = y + stepy / 2;

    g.fillTriangle(x, y, x + stepx, y, midx, midy);

    g.fillTriangle(midx, midy, x, y + stepy,

    x + stepx, y + stepy);

    }

    }

    }

    }

    // CustomItem methods.

    protected void keyPressed(int keyCode) { toggle(); }

    protected void pointerPressed(int x, int y) { toggle(); }

    }

    Hình chụp của MIDlet khi chạy (hình 1)

    Hình ảnh RGB

    Một cải tiến khác là cách biểu diễn hình ảnh ở dạng mảng cho phép MIDlet thao tác dữ liệu hình ảnh một cách trực tiếp. Mỗi pixel hình ảnh được biểu diễn bởi một số int, với 8 bit cho trị số alpha [(độ trong suốt), red, green, và blue] được thể hiện dưới dạng 0xAARRGGBB. Ví dụ, giá trị 0xff00ff00 là một pixel màu xanh không trong suốt, trong khi 0x80ff0000 là một pixel đỏ trong suốt một nửa.

    Lớp Graphics của MIDP 2.0 hỗ trợ hình ảnh RGB với phương thức sau:

    public void drawRGB(int[] rgbData, int offset, int scanlength,

    int x, int y, int width, int height,

    boolean processAlpha)

    Dữ liệu mảng rgbData ít nhất gồm có các thành phần width*height, vị trí bắt đầu offset. Tham số scanLength mô tả số pixel liên tục giữa các hàng trong mảng số nguyên. Các tham số x, y, width và height mô tả dữ liệu số nguyên sẽ được vẽ trên bề mặt vẽ của Graphics. Cuối cùng, processAlpha là một cờ thể hiện thành phần alpha có được sử dụng hay không. Nếu nó là false, tất cả các pixel trong mảng số nguyên sẽ được xem là không trong suốt.

    Ở ví dụ sau, SnowCrash là một Canvas sử dụng mảng số nguyên mô phỏng màn hình khi mất tín hiệu video.

    import java.util.Random;

    import javax.microedition.lcdui.*;

    import javax.microedition.midlet.*;

    public class SnowCrash

    extends Canvas

    implements Runnable {

    private boolean mTrucking;

    private int[] mRGB;

    private Random mRandom;

    public SnowCrash() {

    mTrucking = true;

    mRandom = new Random();

    Thread t = new Thread(this);

    t.start();

    }

    protected void randomize() {

    if (mRGB == null) return;

    int bitCounter = 0;

    int r = 0;

    for (int i = 0; i < mRGB.length; i++) {

    // Get the next random int if necessary.

    if (bitCounter == 0) {

    r = mRandom.nextInt();

    bitCounter = 32;

    }

    // Get the next bit.

    int bit = r % 2;

    r = (r >> 1);

    bitCounter--;

    // Set the color to black or white.

    mRGB[i] = (bit == 0) ? 0xff000000 : 0xffffffff;

    }

    }

    public void stop() { mTrucking = false; }

    // Canvas abstract method

    public void paint(Graphics g) {

    int w = getWidth();

    int h = getHeight();

    int rw = 50;

    int rh = 50;

    int rx = (w - rw) / 2;

    int ry = (h - rh) / 2;

    if (mRGB == null) mRGB = new int[rw * rh];

    // Clear the screen.

    g.setColor(0xffffffff);

    g.fillRect(0, 0, w, h);

    // Draw the outline.

    g.setColor(0xff000000);

    g.drawRect(rx, ry, rw + 1, rh + 1);

    // Draw the snow.

    g.drawRGB(mRGB, 0, rw, rx + 1, ry + 1, rw, rh, false);

    }

    // Runnable method

    public void run() {

    // Attempt 12 fps.

    int interval = 1000 / 12;

    while (mTrucking) {

    randomize();

    repaint();

    try { Thread.sleep(interval); }

    catch (InterruptedException ie) {}

    }

    }

    }

    Màn hình của SnowCrash khi chạy (hình 2)

    Lời kết

    Ngoài những điểm kể trên, MIDP 2.0 còn có nhiều tính năng mới khác như: Cơ chế Push Registry cho phép kích hoạt MIDlet từ server, chuẩn hóa chuỗi kết nối cho truy xuất cổng serial, lưu trữ chia sẻ giữa các MIDlet... Tóm lại, MIDP 2.0 đã mở rộng đáng kể trên đặc tả gốc của MIDP 1.0, mang lại nhiều tính năng hữu ích cho các nhà phát triển ứng dụng di động.

    Lê Ngọc Quốc Khánh
    step2 – JavaVietnam.org

    --------------------------------
    Tài liệu tham khảo:
    1. Jonathan Knudsen – Whats new in MIDP 2.0 – Sun Developer Network 2002 (http://developers.sun.com/techtopics/mobility/midp/articles/midp20/index.html)
    2. MIDP Documentation – Whats new in MIDP 2.0 – Sun Developer Network (
    http://java.sun.com/products/midp/whatsnew.html

    ID: A0507_125