Xử lý màn hình chờ
Để cải tiến SimpleWaitMIDlet, chúng ta sẽ xử lý phương thức connect() vào một lớp riêng biệt, gọi là CleanWorker, lúc đó ta sẽ đổi lại SimpleWaitMIDlet thành CleanMIDlet.
Bởi vì mạng không dây có xu hướng chậm và không ổn định, nên ta sẽ thêm một tùy chọn để người dùng có thể hủy kết nối nếu chờ quá lâu.
CleanMIDlet sẽ xử lý việc tạo ra các command và lưu trữ một tham chiếu vào một biến thành viên có tên là mCancelCommand; đồng thời CleanMIDlet là một CommandListener chung cho cả mainform và waitform.
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class CleanMIDlet extends MIDlet implements CommandListener {
private Display mDisplay;
private Form mMainForm, mWaitForm;
private Command mExitCommand, mConnectCommand, mCancelCommand;
private CleanWorker mWorker;
public void startApp() {
mDisplay = Display.getDisplay(this);
if (mMainForm == null) {
mMainForm = new Form(“CleanMIDlet”);
mMainForm.append(new StringItem(“”, “Select Connect to make a network connection”));
mExitCommand = new Command(“Exit”, Command.EXIT, 0);
mConnectCommand = new Command(“Connect”, Command.SCREEN, 0);
mMainForm.addCommand(mExitCommand);
mMainForm.addCommand(mConnectCommand);
mMainForm.setCommandListener(this);
mWaitForm = new Form(“Waiting…”);
mCancelCommand = new Command(“Cancel”, Command.CANCEL, 0);
mWaitForm.addCommand(mCancelCommand);
mWaitForm.setCommandListener(this);
}
mDisplay.setCurrent(mMainForm);
}
public void commandAction(Command c, Displayable s) {
if (c == mExitCommand)
notifyDestroyed();
else if (c == mConnectCommand) {
mDisplay.setCurrent(mWaitForm);
String url = getAppProperty(“NetworkThreading.URL”);
mWorker = new CleanWorker(this, url);
mWorker.start();
}
else if (c == mCancelCommand) {
mDisplay.setCurrent(mMainForm);
mWorker.cancel();
mWorker = null;
}
}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {}
public void networkResponse(String s) {
Alert a = new Alert(“Response”, s, null, null);
a.setTimeout(Alert.FOREVER);
mDisplay.setCurrent(a, mMainForm);
}
public void networkException(IOException ioe) {
Alert a = new Alert(“Exception”, ioe.toString(), null, null);
a.setTimeout(Alert.FOREVER);
mDisplay.setCurrent(a, mMainForm);
}
}
Bây giờ, chúng ta xây dựng phương thức connect() trong lớp CleanWorker như sau:
import java.io.*;
import javax.microedition.io.*;
public class CleanWorker extends Thread {
private CleanMIDlet mMIDlet;
private String mURL;
private HttpConnection mHttpConnection;
private boolean mCancel;
public CleanWorker(CleanMIDlet midlet, String url) {
mMIDlet = midlet;
mURL = url;
mCancel = false;
}
public void run() {
connect();
}
public void cancel() {
try {
mCancel = true;
if (mHttpConnection != null)
mHttpConnection.close();
}
catch (IOException ignored) {}
}
private void connect() {
InputStream in = null;
try {
// Query the server and retrieve the response.
mHttpConnection = (HttpConnection)Connector.open(mURL);
mHttpConnection.setRequestProperty(“Connection”, “close”);
in = mHttpConnection.openInputStream();
// Pull back the server’s response. If a content length is not
// specified, we’ll just read 255 bytes.
int contentLength = (int)mHttpConnection.getLength();
if (contentLength == -1) contentLength = 255;
byte[] raw = new byte[contentLength];
int length = in.read(raw);
// Clean up.
in.close();
mHttpConnection.close();
// Show the response to the user.
String s = new String(raw, 0, length);
mMIDlet.networkResponse(s);
}
catch (IOException ioe) {
if (mCancel == false) {
try {
if (in != null) in.close();
if (mHttpConnection != null) mHttpConnection.close();
}
catch (IOException ignored) {}
mMIDlet.networkException(ioe);
}
mCancel = false;
}
}
}
Chỉ sử dụng một thread cho việc kết nối mạng
Ở ví dụ trên, ta thấy mỗi khi người dùng nhấn command Connect, ứng dụng lại tạo ra một thread mới CleanWorker để thực hiện công việc kết nối mạng.
Trên các platform nhỏ chạy MIDP, tạo ra một thread mới sẽ làm tiêu tốn rất nhiều năng lượng(power) và bộ nhớ. Chính vì thế, chúng ta có thể tái sử dụng một thread duy nhất để làm tất cả các công việc kết nối mạng thay vì tạo ra một thread mới mỗi khi người dùng nhấn command Connect. Sơ đồ dưới đây minh hoạ kỹ thuật này.
Trong ví dụ trên,các hoạt động mạng được chia thành một lớp worker riêng biệt, sự thay đổi này không phải là quá khó khăn. Bây giờ, chúng ta sẽ tạo một lớp SingleWorker mới dựa trên lớp CleanWorker. Trong phương thức run(), thay vì gọi phương thức connect() một lần, chúng ta sẽ sử dụng vòng lặp và sử dụng phương thức wait(). Khi một thread khác sử dụng phương thức notify() để đánh thức thread SingleWorker, thì nó sẽ gọi phương thức connect(). Và để notify() thread, ta xây dựng phương thức go() để đánh thức thread đang chờ đợi để tiếp tục thực hiện công việc của mình. Biến thành viên mTrucking là một biến kiểu boolean cho biết thể hiện(instance) SingleWorker hiện đang chạy, hay sẽ được kết thúc.
public synchronized void run() {
while (mTrucking) {
try { wait();
}
catch (InterruptedException ie) {}
if (mTrucking) connect();
}
}
public synchronized void go() {
notify();
}
Chúng ta sẽ xây dựng lớp SingleWorker như sau:
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class SingleMIDlet extends MIDlet implements CommandListener {
private Display mDisplay;
private Form mMainForm, mWaitForm;
private SingleWorker mWorker;
private Command mExitCommand, mConnectCommand, mCancelCommand;
public void startApp() {
mDisplay = Display.getDisplay(this);
if (mMainForm == null) {
mMainForm = new Form(“SingleMIDlet”);
mMainForm.append(new StringItem(“”, “Select Connect to make a network connection”));
mExitCommand = new Command(“Exit”, Command.EXIT, 0);
mConnectCommand = new Command(“Connect”, Command.SCREEN, 0);
mMainForm.addCommand(mExitCommand);
mMainForm.addCommand(mConnectCommand);
mMainForm.setCommandListener(this);
mWaitForm = new Form(“Waiting…”);
mCancelCommand = new Command(“Cancel”, Command.CANCEL, 0);
mWaitForm.addCommand(mCancelCommand);
mWaitForm.setCommandListener(this);
String url = getAppProperty(“NetworkThreading.URL”);
mWorker = new SingleWorker(this, url);
mWorker.start();
}
mDisplay.setCurrent(mMainForm);
}
public void commandAction(Command c, Displayable s) {
if (c == mExitCommand)
notifyDestroyed();
else if (c == mConnectCommand) {
mDisplay.setCurrent(mWaitForm);
mWorker.go();
}
else if (c == mCancelCommand) {
mDisplay.setCurrent(mMainForm);
mWorker.cancel();
}
}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {
mWorker.stop();
}
public void networkResponse(String s) {
Alert a = new Alert(“Response”, s, null, null);
a.setTimeout(Alert.FOREVER);
mDisplay.setCurrent(a, mMainForm);
}
public void networkException(IOException ioe) {
Alert a = new Alert(“Exception”, ioe.toString(), null, null);
a.setTimeout(Alert.FOREVER);
mDisplay.setCurrent(a, mMainForm);
}
}
Bạn thấy bài viết này thế nào?
Các bài liên quan:
Sử dụng Thread hiệu quả trong J2ME – Phan 1
Sử dụng Thread hiệu quả trong J2ME – Phan 2
Sử dụng Thread hiệu quả trong J2ME – Phan 4


6 responses to “Sử dụng Thread hiệu quả trong J2ME – Phan 3”
nguyễn thiện dũng
February 26th, 2010 at 10:44
anh cho em hỏi, làm thế nào để mình thêm được các item vào trong canvas ví dụ như textfield vào trong canvas:
nếu được thì anh cho em xin code ví dụ nghe
cảm ơn anh nhiều
mobilesprogramming
February 26th, 2010 at 11:31
Bạn có thể tham khảo class diagram trong J2ME tại địa chỉ:
http://mobilesprogramming.wordpress.com/2010/01/16/phat-tri%E1%BB%83n-game-d%C6%A1n-gian-tren-mobilep2/
Trong J2ME, các items như: TextField không cho phép được add vào trong Canvas, bạn chỉ có thể vẽ một đối tượng mô phỏng dạng TextField thôi.Bạn có thể tham khảo tại đây:
http://wiki.forum.nokia.com/index.php/Custom_Text_Input_in_Java_ME
nguyễn thiện dũng
February 26th, 2010 at 19:47
thanks anh nhiều.thì ý của em là hỏi anh cách vẽ những control nhập liệu đó trong canvas.
nguyễn thiện dũng
February 26th, 2010 at 20:55
trang này của anh đưa rất hay, nhưng rất tiểc chi có một truờng hợp là text input
còn những item khác thì em tim trên mạng mà ít tài liệu nào huớng dẫn cách làm.
mobilesprogramming
February 26th, 2010 at 22:31
Bạn thử tìm hiểu link này xem:http://mobilesprogramming.wordpress.com/2010/01/16/java-me-ui-frameworks-p1/
nguyễn thiện dũng
February 27th, 2010 at 08:34
thank anh nhiều!