Простой фрагмент кода мидлета (класс Moo) ниже (после выдержек) взаимоблокируется (по крайней мере, я предполагаю, что он заблокирован после прочтения этого поста в темах здесь ).
Я воспроизвел соответствующие выдержки из поста:
String url = ...
Connection conn = null;
try {
conn = Connector.open( url );
// do something here
}
catch( IOException e ){
// error
}
Корень проблемы заключается в блокирующем характере вызова open (). На некоторых платформах система выполняет фактическое соединение под крышками, эквивалентно отдельному потоку. Вызывающий поток блокируется, пока поток соединения не установит соединение. В то же время подсистема безопасности может потребовать, чтобы пользователь подтвердил соединение, и поток соединений блокируется, пока поток событий не получит подтверждение от пользователя. Произошла взаимоблокировка, поскольку поток событий уже ожидает поток подключения.
public class Moo extends MIDlet {
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
// TODO Auto-generated method stub
}
protected void pauseApp() {
}
protected void startApp() throws MIDletStateChangeException {
Display display = Display.getDisplay(this);
MyCanvas myCanvas = new MyCanvas();
display.setCurrent(myCanvas);
myCanvas.repaint();
}
class MyCanvas extends Canvas {
protected void paint(Graphics graphics) {
try {
Image bgImage = Image.createImage(getWidth(), getHeight());
HttpConnection httpConnection = (HttpConnection) Connector
.open("http://stackoverflow.com/content/img/so/logo.png");
Image image = Image.createImage(httpConnection
.openInputStream());
bgImage.getGraphics().drawImage(image, 0, 0, 0);
httpConnection.close();
graphics.drawImage(bgImage, 0, 0, 0);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Может кто-нибудь сказать мне, как здесь осуществляется вызов системного потока (потоки событий и уведомлений) и последовательность событий, ведущих к тупику. Мне не ясно, какие нити здесь приводят к тупику.
- Есть ли документация по модели потоков j2me?
- Где я могу получить исходные коды для системных классов j2me (я хочу проверить реализацию классов Connection)?
РЕДАКТИРОВАТЬ : В приведенном выше коде я получаю логику. Но приведенный ниже код должен по крайней мере работать правильно? Этот также блокирует, где я делаю сетевое соединение в отдельном потоке.
<code>
public class Foo extends MIDlet {
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
// TODO Auto-generated method stub
}
protected void pauseApp() {
// TODO Auto-generated method stub
}
protected void startApp() throws MIDletStateChangeException {
Display display = Display.getDisplay(this);
MyCanvas myCanvas = new MyCanvas();
display.setCurrent(myCanvas);
myCanvas.repaint();
}
class MyCanvas extends Canvas {
protected void paint(Graphics graphics) {
try {
Image bgImage = Image.createImage(getWidth(), getHeight());
FetchImage fetchImage = new FetchImage();
Thread thread = new Thread(fetchImage);
thread.start();
thread.join();
bgImage.getGraphics().drawImage(fetchImage.image, 0, 0, 0);
graphics.drawImage(bgImage, 0, 0, 0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class FetchImage implements Runnable {
public Image image;
public void run() {
HttpConnection httpConnection;
try {
httpConnection = (HttpConnection) Connector
.open("http://10.4.71.200/stage/images/front/car.png");
image = Image.createImage(httpConnection.openInputStream());
httpConnection.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}