BlackBerry Forums Support Community               

Closed Thread
 
LinkBack Thread Tools
Old 11-20-2007, 08:06 AM   #1 (permalink)
Knows Where the Search Button Is
 
Join Date: Nov 2007
Model: 8700c
PIN: N/A
Carrier: AT&T
Posts: 32
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default Calling networking sub-thread

Please Login to Remove!

Newbie in dire need of help again.

My networking thread is as follows..

Code:
private class ConnectionThread extends Thread
       {
           public void run()
           {
                try
                {
                    conn = (HttpConnection)Connector.open(URL);
                    yearLabel.setText(URL);
                    conn.setRequestMethod(HttpConnection.GET);
                    conn.setRequestProperty("User-Agent", "BlackBerry/4.2.1");
                    String lang = conn.getRequestProperty("Content-Language");
                    
                    int rc = conn.getResponseCode();
                   
                    InputStream in = conn.openInputStream();
                    byte[] data = new byte[256];
                    int len = 0;
                    StringBuffer raw = new StringBuffer();
                    while (-1 != (len = in.read(data)) )
                    {
                        raw.append(new String(data, 0, len));
                    }
                    text = raw.toString();
                    in.close();
                    // more things to do after that
                    // i.e, processing the data received
How do i actually call this? I've tried searching for examples and only come across one in the BB development guide, and the same example on google.

I'm calling it as follows at the moment and ofcourse it's not working fine..

Code:
// Do other things
_connectionThread.start();
// Do other things
I read something about an invokeLater() but if i put the whole
Code:
UiApplication.getUiApplication().invokeLater(new Runable)
{ 
   public void run()
   {
      _connectionThread.start()
   }
};
it doesn't work. Basically what i'm trying to do is set up a connection each time the user hits a certain button on the screen, download a file, and process it.

Code:
        private FieldChangeListener fieldChangeListener = new FieldChangeListener() 
        { 
             public void fieldChanged(Field field, int context) //respond to button events
             {
                if (field == newCalButton) //if first button selected
                {
                    userMonth = monthChoice.getSelectedValue();
                    userYear = yearChoice.getSelectedValue();
                    
                    _connectionThread.start();

                    numRows = NumberRowsNeeded(userYear, userMonth-1);
                    .... // more code
Help will be greatly appreciated
Offline  
Old 11-20-2007, 01:13 PM   #2 (permalink)
Knows Where the Search Button Is
 
Join Date: Nov 2007
Model: 8700c
PIN: N/A
Carrier: AT&T
Posts: 32
Post Thanks: 0
Thanked 0 Times in 0 Posts
Unhappy

Update on this..

I tried putting the networking thread call in an invokeAndWait block..

Code:
                   URL = "http://www.lunastaa.com/mobile/" + userYear + "_" + userMonth + ".txt";
                    yearLabel.setText(URL);
                    
                    try
                    {
                        UiApplication.getUiApplication().invokeAndWait(new Runnable()
                        {
                            public void run()
                            {
                                ConnectionThread _connectionThread = new ConnectionThread();
                                _connectionThread.start();
                            }
                        });
                    }
                    catch (IllegalThreadStateException t)
                    {
                        eventLabel.setText("Please wait");
                        UiApplication.getUiApplication().pushScreen(popupScreen);
                    }
                    catch (Exception err)
                    {
                    }
                    
                    //yearLabel.setText("Done");

                    numRows = NumberRowsNeeded(userYear, userMonth-1);
                    // some more code
and the networking thread now is as follows..

Code:
       private class ConnectionThread extends Thread
       {
           public void run()
           {
                try
                {
                    URL = "http://www.lunastaa.com/mobile/" + userYear + "_" + userMonth + ".txt";
                    yearLabel.setText("!entered!");
                    conn = (HttpConnection)Connector.open(URL);
                    yearLabel.setText("!" + URL + "!");
                    conn.setRequestMethod(HttpConnection.GET);
                    yearLabel.setText("!get!");
                    conn.setRequestProperty("User-Agent", "BlackBerry/4.2.1");
                    yearLabel.setText("!g1!");
                    String lang = conn.getRequestProperty("Content-Language");
                    yearLabel.setText("!g2!");
All i get to when i click the button (the call to invokeAndWait) is that i see !entered! on the screen. It doesn't get past that step.

What's even more weird is that when i added some print statements to the beginning of the code, it still only displays just the first one and then stops.

The code isn't invoking and waiting either as it's supposed to, it straight away processes the statements after the invokeAndWait block.

I don't even see it pulling any data now when i click a button, minus the initial launch.. sigh

Blah, my code is such a mess now.. I guess i'll really need someone to look at my whole code file and try it for themselves to see what i mean by the issues i'm having. No wonder i always hated java..

Someone, please help!!
Offline  
Old 11-20-2007, 03:08 PM   #3 (permalink)
Talking BlackBerry Encyclopedia
 
richard.puckett's Avatar
 
Join Date: Oct 2007
Location: Seattle, WA
Model: 9020
PIN: N/A
Carrier: T-Mobile
Posts: 212
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hey man, how's it going?

I guess it's personal preference, but my preference is to not wait on networking actions. Generally, when you start a thread you do so because you want some task to run "in the background" and don't want to lock up your app (and/or UI) while waiting for that task to complete.

For something like this, you'd want to draw your components to the screen and then kick off your networking thread via start(). Now, your user is sitting there staring at the UI so if it makes sense you may want to display some kind of progress meter to the user so he knows that things are still happening, eg: "Downloading. Please Wait."

In my networking thread I pass in a listener (a class that implements my NetworkListener interface). Once my networking thread has gotten to an interesting point (connection succeeded or failed) it pings the listener and, if everything worked out, passes downloaded content to it.

Then the networking thread terminates.

The listener will then perform any actions that make sense. It may notify the user that the connection failed or it may update the screen with the content just passed to it by the networking thread, etc.

As a rough example:

public interface NetworkListener {
void downloadComplete(InputStream data);
}

public class NetworkThread extends Thread {
NetworkListener listener;
public NetworkThread(NetworkListener listener) {
this.listener = listener;
}
public void run() {
// do networking stuff
listener.downloadComplete(...);
}
}

public class DoStuff extends MainScreen implements NetworkListener {
public void Foo() {
add(new RichTextField("Doing Stuff"));
new NetworkThread().start(this);
}
public void downloadComplete(InputStream is) {
// Get data, get event lock, update display
}
}
Offline  
Old 02-21-2008, 03:58 PM   #4 (permalink)
Knows Where the Search Button Is
 
Join Date: Oct 2007
Model: 8700g
PIN: N/A
Carrier: T-Mobile
Posts: 21
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hi Richard,

i did the same as your example and i have an issue to update the screen/GUI
or just show an alert.

any ideas?

thanks in advanced,
eyal
__________________
eyal
Offline  
Old 02-21-2008, 04:02 PM   #5 (permalink)
Talking BlackBerry Encyclopedia
 
richard.puckett's Avatar
 
Join Date: Oct 2007
Location: Seattle, WA
Model: 9020
PIN: N/A
Carrier: T-Mobile
Posts: 212
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

What is it you want to do? Give me an example and I'll see if I can be of any help.
Offline  
Old 02-21-2008, 04:16 PM   #6 (permalink)
Knows Where the Search Button Is
 
Join Date: Oct 2007
Model: 8700g
PIN: N/A
Carrier: T-Mobile
Posts: 21
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

i have the same implementation starting a thread that calls a web service.
i wnat to be able to get back to my screen and update the GUI when the web service is done.

so on your example downloadComplete(...) finished and i want to go back to the main screen ("doStaff class on your example) class and for example alert the user.

is that more clear ?

thanks
eyal
__________________
eyal
Offline  
Old 02-21-2008, 04:36 PM   #7 (permalink)
Talking BlackBerry Encyclopedia
 
richard.puckett's Avatar
 
Join Date: Oct 2007
Location: Seattle, WA
Model: 9020
PIN: N/A
Carrier: T-Mobile
Posts: 212
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

If DoStuff invoked is the NetworkListener then its downloadComplete method will be called when networking has about wrapped up. In that method you can then do whatever you want: add RichTextFields, pop and push Screens, etc. Note that in my example, DoStuff remains the active screen and would still be visible while networking was going on in the background.
Offline  
Old 02-21-2008, 04:53 PM   #8 (permalink)
Knows Where the Search Button Is
 
Join Date: Oct 2007
Model: 8700g
PIN: N/A
Carrier: T-Mobile
Posts: 21
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

i have a Dialog.alert("..."); after i get a response from the web service
and the error i am getting is

"Error pushModalScreen called by a non-event thread"

maybe i misunderstood this error, i am new to the blackberry development.

thanks in advanced,
eyal
__________________
eyal
Offline  
Old 02-21-2008, 05:14 PM   #9 (permalink)
Talking BlackBerry Encyclopedia
 
richard.puckett's Avatar
 
Join Date: Oct 2007
Location: Seattle, WA
Model: 9020
PIN: N/A
Carrier: T-Mobile
Posts: 212
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

On BlackBerry you have to coordinate with the event dispatch thread. You can do this either by synchronizing with it or by handing off a Runnable to it. EG:

Code:
synchronized(Application.getEventLock()) {
   Dialog.alert("Inconceivable Error Occured");
}
or
Code:
Application.getApplication().invokeLater(new Runnable() {
   public void run() {
      Dialog.alert("Another Inconceivable Error Occured!");
   }
});
Offline  
Old 02-22-2008, 08:39 AM   #10 (permalink)
Knows Where the Search Button Is
 
Join Date: Oct 2007
Model: 8700g
PIN: N/A
Carrier: T-Mobile
Posts: 21
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hi

and thank you very much for your help.

i know i need to coordinate with the event dispatch thread.
your first example was exacly what i did and i've got the error.

i try the second example (passing to it a runable) and it works.

thank you very much,
Eyal.
__________________
eyal
Offline  
Old 03-28-2008, 06:37 AM   #11 (permalink)
Thumbs Must Hurt
 
Join Date: Jan 2007
Model: 8800
Carrier: Orange
Posts: 181
Post Thanks: 0
Thanked 0 Times in 0 Posts
Default

I've written a getWebData method that does what you want: Dowling.me.uk Blackberry WebBitmapField
Offline  
Closed Thread


Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On





Copyright 2004-2014 BlackBerryForums.com.
The names RIM and BlackBerry are registered Trademarks of BlackBerry Inc.