Question

Following is the code which is showing the above exception on debugging :

Firstly I am trying to call a class HTTPConnection from the below menu item.

protected MenuItem _SelectDealerItem = new MenuItem("Select Dealer",100,10)
{
    public void run()
    {
        new HTTPConnection();
    }
};

In HTTPConnection Class I am checking the connection type and calling another Class TSelectDealerScreen:

public class HTTPConnection {

ConnectionFactory _factory = new ConnectionFactory();

public HTTPConnection()
{
    int[] _intTransports = {
            TransportInfo.TRANSPORT_TCP_WIFI,
            TransportInfo.TRANSPORT_WAP2,
            TransportInfo.TRANSPORT_TCP_CELLULAR
    };

    for(int i=0;i<_intTransports.length;i++)
    {
        int transport = _intTransports[i];
        if(!TransportInfo.isTransportTypeAvailable(transport)||!TransportInfo.hasSufficientCoverage(transport))
        {
            Arrays.removeAt(_intTransports,i);
        }
    }

    TcpCellularOptions tcpOptions = new TcpCellularOptions();

    if(!TcpCellularOptions.isDefaultAPNSet())
    {
        tcpOptions.setApn("My APN");
        tcpOptions.setTunnelAuthUsername("user");
        tcpOptions.setTunnelAuthPassword("password");
    }

    if(_intTransports.length>0)
    {
        _factory.setPreferredTransportTypes(_intTransports);
    }

    _factory.setTransportTypeOptions(TransportInfo.TRANSPORT_TCP_CELLULAR, tcpOptions);
    _factory.setAttemptsLimit(5);

    Thread t = new Thread(new Runnable()
    {
        public void run()
        {
            ConnectionDescriptor cd = _factory.getConnection("http://excellentrealtors.info/Smart-Trace/get_dealer.php");
            if(cd!=null)
            {
                Connection c = cd.getConnection();
                displayContent(c);
            }
        }
    });
    t.start();
}

private void displayContent(final Connection conn)
{
    UiApplication.getUiApplication().pushScreen(new TSelectDealerScreen(conn));
}
}

In TSelectDealerScreen class i am simply trying to read the stream, but it is showing illegal state exception whenever i try to debug, I am not much familiar to blackberry programming, kindly advice.

public class TSelectDealerScreen extends MainScreen
{
RichTextField _rtfOutput = new RichTextField();

public TSelectDealerScreen(Connection conn) 
{   
    _rtfOutput.setText("Retrieving Data.Please Wait");
    add(_rtfOutput);
    ContentReaderThread t = new ContentReaderThread(conn);
    t.start();
}

private final class ContentReaderThread extends Thread {

    private Connection _connection;

    ContentReaderThread(Connection conn)
    {
        _connection = conn;
    }

    public void run()
    {
        String result = "";
        OutputStream os = null;
        InputStream is = null;

        try
        {
            OutputConnection outputConn = (OutputConnection)_connection;
            os = outputConn.openOutputStream();
            String getCommand = "GET " + "/" + " HTTP/1.0\r\n\r\n";
            os.write(getCommand.getBytes());
            os.flush();

            // Get InputConnection and read the server's response
            InputConnection inputConn = (InputConnection) _connection;
            is = inputConn.openInputStream();
            byte[] data = net.rim.device.api.io.IOUtilities.streamToBytes(is);
            result = new String(data, "US-ASCII");
            // is.close();
            System.out.print(result);
        }
        catch(Exception e)
        {
            result = "ERROR fetching content: " + e.toString();
        }
        finally
        {
            // Close OutputStream
            if(os != null)
            {
                try
                {
                    os.close();
                }
                catch(IOException e)
                {
                }
            }

            // Close InputStream
            if(is != null)
            {
                try
                {
                    is.close();
                }
                catch(IOException e)
                {
                }
            }
            // Close Connection
            try
            {
                _connection.close();
            }
            catch(IOException ioe)
            {
            }
        }
              // Show the response received from the web server, or an error message
        showContents(result);
    }      
}

public void showContents(final String result)
{
    UiApplication.getUiApplication().invokeLater(new Runnable()
    {
        public void run()
        {
            _rtfOutput.setText(result);
        }
    });
}
}
Was it helpful?

Solution

In your HTTPConnection class, you do:

Thread t =  new Thread(new Runnable()
{
    public void run()
    {
        ConnectionDescriptor cd =   _factory.getConnection("http://excellentrealtors.info/Smart-Trace/get_dealer.php");
        if(cd!=null)
        {
            Connection c    =   cd.getConnection();
            displayContent(c);
        }
    }
});
t.start();

That runs everything inside run() on a background thread. But, inside displayContent(c), you do:

UiApplication.getUiApplication().pushScreen(new TSelectDealerScreen(conn));

which is a UI operation.

Trying to modify the UI from a background thread normally causes an IllegalStateException.

I believe you just need to wrap the call to pushScreen() with this:

private void displayContent(final Connection conn) {

    final UiApplication app = UiApplication.getUiApplication();
    app.invokeLater(new Runnable() {
       public void run() {
          // this code is run on the UI thread
          app.pushScreen(new TSelectDealerScreen(conn));
       }
    });
}

Also, if you're an Android developer, and you want help doing normal background/UI thread stuff, you might check out this other answer I wrote on "porting" AsyncTask to BlackBerry Java

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top