10-23-2009 08:29 AM
I am trying to implement threads for making an httpConnection. From examples I have created a class ConnectionThread. On my loginScreen class I call this to start the Thread,
FieldChangeListener bhandler = new FieldChangeListener()
{
public void fieldChanged(Field field, int context)
{
_connectionThread.start();
_connectionThread.fetch("http://apisite.tpinside.com/service.asmx");
UiApplication.getUiApplication().popScreen();
UiApplication.getUiApplication().pushScreen(new portfolioOverviewScreen());
}
};
From an earlier post I changed the way I call the screen to the following,
UiApplication.getUiApplication().invokeLater(new Runnable(){ public void run() {UiApplication.getUiApplication().popScreen();}});
UiApplication.getUiApplication().invokeLater(new Runnable(){ public void run() {UiApplication.getUiApplication().pushScreen(new portfolioOverviewScreen());}});However the popscreen/pushscreen is called prior to the connectionThread finishing its connection. Is there a way I make these wait untill the thread is finished?
10-23-2009 08:30 AM
Use Thread.join.
10-23-2009 08:40 AM
One solution is to invoke the invokeLater (the one that pushes the screen) from the connect thread, after the connection is established. You can invokeLater from any thread -- it simply posts a message to the event queue from the event thread takes the messages and, in the case of invokeLater messages, simply invokes Runnable.run on the runnable that's referenced by the invokeLater message.
10-23-2009 09:23 AM
ydaraishy, sorry I don't understand.
Klyubin, I have tried the following to posting, however the screens never show, but i get all the messages so I know that the call has worked.
public class ConnectionThread extends Thread {
private static final int TIMEOUT = 500; // ms
private String _theUrl;
private volatile boolean _start = false;
private volatile boolean _stop = false;
private StatusThread _statusThread = new StatusThread();
private SoapObject table = null; // Its the table of a DataSet
private SoapObject client = null; // Its the client pettition to the web service
private SoapObject tableRow = null; // Gets the information of a row from the table DataSet
private SoapObject responseBody = null; // Its the whole response of the WebService
private String authResult, passPhraseAvailable, _id, clnt_id, ticket_id;
// Retrieve the URL.
public synchronized String getUrl()
{
return _theUrl;
}
public boolean isStarted()
{
return _start;
}
// Fetch a page.
// Synchronized so that I don't miss requests.
public void fetch(String url)
{
synchronized(this)
{
_start = true;
_theUrl = url;
}
}
// Shutdown the thread.
public void stop()
{
_stop = true;
}
public void run()
{
for(;;)
{
// Thread control.
while( !_start && !_stop)
{
// Sleep for a bit so we don't spin.
try
{
sleep(TIMEOUT);
}
catch (InterruptedException e)
{
System.err.println(e.toString());
}
}
// Exit condition.
if ( _stop )
{
return;
}
// This entire block is synchronized, this ensures I won't miss fetch requests
// made while I process a page.
synchronized(this)
{
// Open the connection and extract the data.
StreamConnection s = null;
try
{
s = (StreamConnection)Connector.open(getUrl());
HttpConnection httpConn = (HttpConnection)s;
int status = httpConn.getResponseCode();
System.out.println("out");
if (status == HttpConnection.HTTP_OK)
{
String serviceUrl = "http://some web service";
String serviceNamespace = "http://tempuri.org/";
String soapAction = "http://tempuri.org/login";
SoapObject rpc = new SoapObject(serviceNamespace, "login");
rpc.addProperty("Username","demo");
rpc.addProperty("Password","demo");
// rpc.addProperty("Username",txtUser.getText());
// rpc.addProperty("Password",txtpass.getText());
("CompanyID",txtAccess.getText());
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut = rpc;
envelope.dotNet = true;
// envelope.encodingStyle = SoapSerializationEnvelope.ENC;
HttpTransport ht = new HttpTransport(serviceUrl);
ht.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
ht.debug = true;
try
{
ht.call(soapAction, envelope);
String result = (envelope.getResult()).toString();
responseBody = (SoapObject) envelope.getResponse();
responseBody = (SoapObject) responseBody.getProperty(1);
table = (SoapObject) responseBody.getProperty(0);
tableRow = (SoapObject) table.getProperty(0);
authResult = tableRow.getProperty("AuthResult").toString();
passPhraseAvailable = tableRow.getProperty("NoPassphrase").toString();
if(authResult.toString().equals("true")){
System.out.println("so far so good");
// set global variables
loginScreen._id = "bcbnbn";
loginScreen._someId = tableRow.getProperty("cljkb").toString();
loginScreen._clnt_id = tableRow.getProperty("ertret").toString();
}else{
// some code....
}
}
catch(org.xmlpull.v1.XmlPullParserException ex2){
}
catch(Exception ex){
Dialog.alert("invalid login details" + ex.toString());
}
System.out.println("stopped");
stopStatusThread();
s.close();
_start = false;
UiApplication.getUiApplication().invokeLater(new Runnable(){ public void run() {UiApplication.getUiApplication().popScreen();}});
UiApplication.getUiApplication().invokeLater(new Runnable(){ public void run() {UiApplication.getUiApplication().pushScreen(new portfolioOverviewScreen());}});
}
else
{
System.out.println("stopped");
stopStatusThread();
}
s.close();
}
catch (IOException e)
{
System.out.println("error");
System.err.println(e.toString());
stopStatusThread();
}
// We're done one connection so reset the start state.
_start = false;
}
}
}
private void stopStatusThread()
{
_statusThread.pause();
try
{
synchronized(_statusThread)
{
// Check the paused condition, incase the notify fires prior to our wait, in which
// case we may never see that nofity.
while ( !_statusThread.isPaused() );
{
_statusThread.wait();
}
}
}
catch (InterruptedException e)
{
System.err.println(e.toString());
}
}
}
10-23-2009 10:00 AM
my stupidity, i was ending the thread to early, made a change and now I am navigating to the pages. Thanks for the pointers!
System.out.println("stopping");
UiApplication.getUiApplication().invokeLater(new Runnable(){
public void run() {
UiApplication.getUiApplication().popScreen();
UiApplication.getUiApplication().pushScreen(new portfolioOverviewScreen());
}});
stopStatusThread();
s.close();
System.out.println("stopped");