1

以下是在调试时显示上述异常的代码:

首先,我试图从下面的菜单项中调用一个类 HTTPConnection。

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

在 HTTPConnection 类中,我正在检查连接类型并调用另一个类 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));
}
}

在 TSelectDealerScreen 类中,我只是试图读取流,但每当我尝试调试时它都会显示非法状态异常,我对黑莓编程不太熟悉,请提供建议。

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);
        }
    });
}
}
4

1 回答 1

0

在你的HTTPConnection课堂上,你会:

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();

run()这在后台线程上运行所有内容。但是,在里面displayContent(c),你做:

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

这是一个 UI 操作。

尝试从后台线程修改 UI 通常会导致IllegalStateException.

我相信你只需要用pushScreen()这个来结束调用:

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));
       }
    });
}

此外,如果您是一名 Android 开发人员,并且需要帮助做普通的后台/UI 线程工作,您可以查看我在“将 AsyncTask 移植到 BlackBerry Java”上写的其他答案

于 2013-04-19T21:15:04.113 回答