05-31-2010 04:30 PM
I use parameter ConnectionTimeout in my url to make an http query.
This part is a combination of lines in my code to represent the principal objects...
StreamConnection s = null;
url = http://devshed.destination.ca/ispcentral_api.php?action_type=recherche;ConnectionTimeout=2000
s = (StreamConnection)Connector.open(url, Connector.READ, true);
HttpConnection httpConn = (HttpConnection)s;
status = httpConn.getResponseCode();
ConnectionTimeout working on simulator but not on device ... Any idea why it's doing that?
05-31-2010 04:34 PM
Does this help you :
http://supportforums.blackberry.com/t5/Java-Develo
06-01-2010 08:44 AM - edited 06-01-2010 08:46 AM
Doesn't really help me. When I use deviceside=true, it is choosing the Direct TCP protocol and the parameter ConnectionTimeout is only working with MDS service. My goal is to use the ConnectionTimeout=19000 in the url so my http query isn't blocking my app for more than 19 seconds.
If for any reason you could give me a tips to make work a connection timeout in another way...ON MY BLACKBERRY 8330 DEVICE, then I would greatly appreciate!
Thank you.
06-01-2010 09:02 AM
Hello,
there is no way to cancel a network i/o as the thread is blocked. You can start the connection on it own thread and show a popupscreen indicating something is going on. After your 19 sec, you can pop the popup and put a flag on the connection thread to invalidate the result.
This way, when the connection timeout or return but the flag is up, the result can be ignored as the user is already doing something else.
06-01-2010 12:00 PM
I used the same code as the sample of Peter_Strange :
I am already using a thread apart to make my connection.
Can you explain me why the url parameter ConnectionTimeout is working only on the simulator 8330? Is there a way to override a function somewhere to make it work? What am I missing?
06-01-2010 12:05 PM
The ConnectionTimeout parameter is only understood by the BES system.
When you are doing a direct TCP connection, it will be ignored.
Please see this KB article:
06-01-2010 01:47 PM
This is a part of my code...I want to be able to pass an error to my ObserverInterface if the timeout occurs...
--------------------------------------------------
[...]
String[] credential = functions.getCrendential();
String url = "http://xxx.xxxxxxxxx.xx/php-bin/ispcentral_api.php
httpRequest(url);
[..]
private class ConnectionThread extends Thread
{
private ObserverInterface _ourObserver;
private String _theUrl;
boolean willFail = false;
public ConnectionThread(ObserverInterface observer) {
super();
_ourObserver = observer;
}
public synchronized String getUrl() {
return _theUrl;
}
public synchronized void start(String url) {
synchronized(this) {
strUrl = _theUrl = url;
}
super.start();
}
/*public void stop() {
this.interrupt();
processing = false;
}*/
private void observerStatusUpdate(final int status, final String statusString) {
_ourObserver.processStatusUpdate(status, statusString);
}
private void observerError(int errorCode, String errorMessage) {
_ourObserver.processError(errorCode, errorMessage);
}
public void observerResponse(String strContent) {
_ourObserver.processResponse(strContent);
}
public void run() {
observerStatusUpdate(25, "Démarrage");
StreamConnection s = null;
try{
String url = getUrl();
StringBuffer bufUrl = new StringBuffer();
while (url.indexOf(" ") != -1){
int index = url.indexOf(" ");
bufUrl.append(url);
bufUrl.deleteCharAt(index);
bufUrl.insert(index, "%20");
url = bufUrl.toString();
}
url += ";ConnectionTimeout=" + TIMEOUT + ";deviceside=false";
observerStatusUpdate(50, "En cours...");
s = (StreamConnection)Connector.open(url, Connector.READ, true);
HttpConnection httpConn = (HttpConnection)s;
int status = 0;
try {
status = httpConn.getResponseCode();
} catch (InterruptedIOException e) {
} catch (IOException e){
}
if (status == HttpConnection.HTTP_OK){
// Lecture des données
InputStream input = s.openInputStream();
byte[] data = new byte[256];
int len = 0;
int size = 0;
StringBuffer raw = new StringBuffer();
while ( -1 != (len = input.read(data)) ){
raw.append(new String(data, 0, len));
size += len;
}
String strContent = raw.toString();
if (strContent.equalsIgnoreCase("END-OF-FILE;")) {
noContent = true;
} else {
noContent = false;
}
strHttpData = strContent;
observerStatusUpdate(100, "Terminée");
if ( willFail ) {
observerError(ObserverInterface.ERROR, "Échec");
} else {
observerResponse(strContent);
}
input.close();
} else {
if (status == 0) {
observerError(ObserverInterface.ERROR, "Délais dépassé...");
} else {
observerError(ObserverInterface.ERROR, Integer.toString(status));
}
System.out.println("Status de l'erreur:"+status);
}
s.close();
_ourObserver = null;
}
catch (IOException e){
System.err.println(e.toString());
}
}
}
public void httpRequest(String url) {
PleaseWaitPopupScreen _waitScreen = new PleaseWaitPopupScreen("Message", "Téléchargement", url);
_waitScreen.show();
}
public class PleaseWaitPopupScreen extends PopupScreen
implements ObserverInterface {
String _title;
private GaugeField _gaugeField = null;
private LabelField _statusText = null;
private ConnectionThread _connectionThread = null;
String _requestURL = null;
byte [] response;
private int _returnCode = ObserverInterface.CANCELLED;
public PleaseWaitPopupScreen(String title, String text, String requestURL) {
super(new VerticalFieldManager());
this.add(new LabelField(title, LabelField.FIELD_HCENTER));
this.add(new SeparatorField());
this.add(new RichTextField(text, Field.READONLY|Field.NON_FOCUSABLE));
_gaugeField = new GaugeField(null, 1, 100, 1, GaugeField.NO_TEXT);
this.add(_gaugeField);
this.add(new SeparatorField());
_statusText = new LabelField("Démarrage");
this.add(_statusText);
_requestURL = requestURL;
}
public int show() {
_connectionThread = new ConnectionThread(this);
_connectionThread.start(_requestURL);
UiApplication.getUiApplication().pushModalScreen(t
return _returnCode;
}
public void processStatusUpdate(final int status, final String statusString) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run () {
_statusText.setText(statusString);
if ( status > 0 ) {
_gaugeField.setValue(status);
}
PleaseWaitPopupScreen.this.invalidate();
}
});
}
public void processResponse(final String response) {
_returnCode = ObserverInterface.OK;
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run () {
UiApplication.getUiApplication().popScreen(Please
}
});
}
public void processError(int errorCode, final String errorMessage) {
_returnCode = errorCode;
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run () {
Dialog.alert("Erreur:\n" + errorMessage);
UiApplication.getUiApplication().popScreen(Please
}
});
}
}
public interface ObserverInterface {
public void processStatusUpdate(int status, String statusString);
public void processResponse(String strContent);
public void processError(int errorCode, String errorMessage);
public static int CANCELLED = -1;
public static int ERROR = -2;
public static int OK = 0;
}
--------------------------------------------------
06-01-2010 01:53 PM
Yes, of course it does - this is expected behavior when pushing a modal screen from the event thread.
06-01-2010 02:13 PM - edited 06-01-2010 02:39 PM
First question:
You say I have to count from outside my thread to know if i'm in timeout? Then if my event thread is blocked, then where could I start my timer? Do I have to start another thread at the same time? Like a status thread to kill the connection thread if its in timeout?
Second question:
My button cancel isn't working ... poping error Uncaught exception: popScreen:
error --> UiEngine is null != net.rim.device.api.ui.UiEngineImpl@fde9e9dc <--
line --> UiApplication.getUiApplication().popScreen(PleaseW
Why?
Code new version...blocks at red line...
Blue is the button cancel with its event...
private class ConnectionThread extends Thread
{
private ObserverInterface _ourObserver;
private String _theUrl;
boolean willFail = false;
public ConnectionThread(ObserverInterface observer) {
super();
_ourObserver = observer;
}
public synchronized String getUrl() {
return _theUrl;
}
public synchronized void start(String url) {
synchronized(this) {
strUrl = _theUrl = url;
}
super.start();
}
public void stop() {
// Tell our observer
observerError(ObserverInterface.CANCELLED, "Cancelled by User");
//_stopRequest = true; // Will no longer tell Observer anything
this.interrupt(); // Give our Thread a kick
}
private void observerStatusUpdate(final int status, final String statusString) {
_ourObserver.processStatusUpdate(status, statusString);
}
private void observerError(int errorCode, String errorMessage) {
_ourObserver.processError(errorCode, errorMessage);
}
public void observerResponse(String strContent) {
_ourObserver.processResponse(strContent);
}
public void run() {
observerStatusUpdate(25, "Démarrage");
StreamConnection s = null;
try{
String url = getUrl();
StringBuffer bufUrl = new StringBuffer();
while (url.indexOf(" ") != -1){
int index = url.indexOf(" ");
bufUrl.append(url);
bufUrl.deleteCharAt(index);
bufUrl.insert(index, "%20");
url = bufUrl.toString();
}
url += ";ConnectionTimeout=" + TIMEOUT + ";deviceside=false";
observerStatusUpdate(50, "En cours...");
s = (StreamConnection)Connector.open(url, Connector.READ, true);
HttpConnection httpConn = (HttpConnection)s;
int status = 0;
try {
status = httpConn.getResponseCode();
} catch (InterruptedIOException e) {
} catch (IOException e){
}
if (status == HttpConnection.HTTP_OK){
// Lecture des données
InputStream input = s.openInputStream();
byte[] data = new byte[256];
int len = 0;
int size = 0;
StringBuffer raw = new StringBuffer();
while ( -1 != (len = input.read(data)) ){
raw.append(new String(data, 0, len));
size += len;
}
String strContent = raw.toString();
if (strContent.equalsIgnoreCase("END-OF-FILE;")) {
noContent = true;
} else {
noContent = false;
}
strHttpData = strContent;
observerStatusUpdate(100, "Terminée");
if ( willFail ) {
observerError(ObserverInterface.ERROR, "Échec");
} else {
observerResponse(strContent);
}
input.close();
} else {
if (status == 0) {
observerError(ObserverInterface.ERROR, "Délais dépassé...");
} else {
observerError(ObserverInterface.ERROR, Integer.toString(status));
}
System.out.println("Status de l'erreur:"+status);
}
s.close();
_ourObserver = null;
}
catch (IOException e){
System.err.println(e.toString());
}
}
}
public void httpRequest(String url) {
PleaseWaitPopupScreen _waitScreen = new PleaseWaitPopupScreen("Message", "Téléchargement", url);
_waitScreen.show();
}
public class PleaseWaitPopupScreen extends PopupScreen
implements ObserverInterface {
String _title;
private GaugeField _gaugeField = null;
private LabelField _statusText = null;
private ButtonField _cancelButton = null;
private ConnectionThread _connectionThread = null;
String _requestURL = null;
byte [] response;
private int _returnCode = ObserverInterface.CANCELLED;
public PleaseWaitPopupScreen(String title, String text, String requestURL) {
super(new VerticalFieldManager());
this.add(new LabelField(title, LabelField.FIELD_HCENTER));
this.add(new SeparatorField());
this.add(new RichTextField(text, Field.READONLY|Field.NON_FOCUSABLE));
_gaugeField = new GaugeField(null, 1, 100, 1, GaugeField.NO_TEXT);
this.add(_gaugeField);
this.add(new SeparatorField());
_statusText = new LabelField("Démarrage");
this.add(_statusText);
_requestURL = requestURL;
_cancelButton = new ButtonField("Cancel", ButtonField.FIELD_HCENTER | ButtonField.CONSUME_CLICK);
_cancelButton.setChangeListener( new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
if ( _connectionThread != null ) {
if ( _connectionThread.isAlive() ) {
_connectionThread.stop();
// This will send us a 'failure' notification
}
} else {
// Something has gone really wrong?!
throw new RuntimeException("Oppsss");
}
}
});
this.add(_cancelButton);
_cancelButton.setFocus();
}
public int show() {
_connectionThread = new ConnectionThread(this);
_connectionThread.start(_requestURL);
UiApplication.getUiApplication().pushModalScreen(
return _returnCode;
}
public void processStatusUpdate(final int status, final String statusString) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run () {
_statusText.setText(statusString);
if ( status > 0 ) {
_gaugeField.setValue(status);
}
PleaseWaitPopupScreen.this.invalidate();
}
});
}
public void processResponse(final String response) {
_returnCode = ObserverInterface.OK;
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run () {
UiApplication.getUiApplication().popScreen(Please
}
});
}
public void processError(int errorCode, final String errorMessage) {
_returnCode = errorCode;
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run () {
Dialog.alert("Erreur:\n" + errorMessage);
UiApplication.getUiApplication().popScreen(PleaseW
//Same error as if it wasn't executed on the event thread...is it possible?
}
});
}
}
public interface ObserverInterface {
public void processStatusUpdate(int status, String statusString);
public void processResponse(String strContent);
public void processError(int errorCode, String errorMessage);
public static int CANCELLED = -1;
public static int ERROR = -2;
public static int OK = 0;
}
06-01-2010 03:15 PM
I think you have wandered off the original topic now. You should probably close this thread (mark "solved
and start another for the other issue.