2

I want to open a dialog from a separate thread, but when using the synchronized way, I get an error.

If I use the method invokeAndWait everything works fine, however I don't understand why I can't use synchronized.

Here is the code I call in my screen:

public void Login() {

        new HttpRequestDispatcher("http://www.google.com", "GET", this) {
            public void onSuccess(byte[] baos, String contentType) {
                synchronized(UiApplication.getEventLock()){
                    Dialog.alert("Cooooooool....");
                }
            }
            public void onFail(String message){
                synchronized(UiApplication.getEventLock()){
                    Dialog.alert(message);
                }
            }
        }.start();
    }

Here is the HttpRequestDispatcherThread:

public abstract class HttpRequestDispatcher extends Thread {

    String url;
    String method;
    Screen scr;

    public HttpRequestDispatcher(String url, String method, Screen scr) {
        this.url = url;
        this.method = method;
        this.scr = scr;
    }

    public abstract void onFail(String message);
    public abstract void onSuccess(byte[] baos, String contentType);
    public void beforeSend() {}
    public void onComplete() {}

    public void run() {

        beforeSend();

        try {

            HttpConnection connection = (HttpConnection) Connector.open(url);
            connection.setRequestMethod(method);

            int responseCode = connection.getResponseCode();
            if (responseCode != HttpConnection.HTTP_OK) {
                onFail(connection.getResponseMessage());
                connection.close();
                return;
            }

            String contentType = connection.getHeaderField("Content-type");
            int contentLength = (int) connection.getLength();
            if (contentLength < 0)
                contentLength = 10000;

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            InputStream responseData = connection.openInputStream();
            byte[] buffer = new byte[contentLength];
            int bytesRead = responseData.read(buffer);

            while (bytesRead > 0) {
                baos.write(buffer, 0, bytesRead);
                bytesRead = responseData.read(buffer);
            }

            baos.close();
            connection.close();

            onComplete();
            onSuccess(baos.toByteArray(), contentType);

        } catch (Exception e) {
        }
    }
}

I get this error in the simulator: "JVM Error 104 Uncought: ArrayIndexOutOfBoundsException"

danielrvt-sgb
  • 1,118
  • 5
  • 17
  • 33

1 Answers1

2

Found the answer:

"Dialogs cannot be opened from a thread other than the main event thread"

Synchronized executes a statement in the current thread but holding the event lock, instead, invokeAndWait, sends the statement to an event queue to be executed later on the main event thread.

Thats why my code didn't work with synchronized

This helped: https://stackoverflow.com/a/6515542/1680787

@Nate, you are absolutly right about my catch blocks, +1 and my bad, just new to blackberry.

Community
  • 1
  • 1
danielrvt-sgb
  • 1,118
  • 5
  • 17
  • 33
  • 1
    Gotcha. So, the problem was actually calling `Dialog.alert()` from the background, but since you trapped that exception and didn't print it with your `catch(Exception e){}` handler, the system never propagated that error. Your program must have then proceeded to have a **second**, possibly unrelated error, that was **not** caught, and resulted in you seeing `ArrayIndexOutOfBoundsException`. So, that was kind of a *red herring*. Printing out exceptions in your catch handler would have shown: `java.lang.RuntimeException: pushModalScreen called by a non-event thread` – Nate Jan 30 '13 at 22:49