Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
New Developer
Posts: 86
Registered: ‎01-20-2012
My Device: Bold Touch

Re: How to replace a bitmapField in the mainscreen?

[ Edited ]

 

Hi all,

 

I have tried setting images from a background thread using static images and it works fine. but i cant do it with the streaming images which I really dont understand why and I kind of tried to work around it by pushing it as a new screen in with the reference i had created to tmy main screen from the background thread. Here is what i did if you think there is a better way please suggest

 

synchronized (UiApplication.getEventLock()) 
{			

try
{
	net.rim.device.api.ui.Screen scr = UiApplication.getUiApplication().getActiveScreen();
	camView.jpegBytes = jp;
	System.out.println("Trying to set the images!!!");
	camView.bmpImage = Bitmap.createBitmapFromBytes(jp, 0, jp.length, 1);
	System.out.println("Created Bitmap Image: " + camView.bmpImage);
	camView.bmpStream.setBitmap(camView.bmpImage);
	System.out.println("Created Bitmap Image: " + camView.bmpStream);
	
	UiApplication.getUiApplication().pushScreen(camView);						
	//camView.updateDisplay();
	
	System.out.println("Image Display Success");
}
catch(IllegalArgumentException ex)
{
	System.out.println("Image Display Exception: " + ex.getMessage());
}
catch(Exception ex)
{
	System.out.println("Exceptionn while displaying images: " + ex.getMessage());					
}
}

 Also as i read in some thread it said " invalidate() only schedules a repaint, which is added to the event queue to be done at some later time." and looking at whats happening with my situation I dont konw when it will repaint. because im streaming these images on the background thread.

 

cheers

Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various

Re: How to replace a bitmapField in the mainscreen?

A few thoughts:

1) Get into a habit of using invokeLater rather than synchronizing on the event lock - it is much safer. In addition, do that only for the parts that update UI. createBitmapFromBytes, for example, has no right whatsoever to run on Event Thread (or while holding event lock). setBitmap, on the other hand, does need the Event Thread to work on displayed BitmapFields.

2) This code looks like the initial creation of the screen - you need to pushScreen only once in the described scenario. What is the code that's running in the background Thread?

3) invalidate schedules things on Event Thread, which runs separately from your background one. So it will repaint as soon as it's done doing other UI stuff. Of course, if your background thread has an equal or higher priority and is doing only CPU operations, you can hang your UI for some very long time. However, any blocking operation such as a file read or an HTTP request on the background thread will free the CPU for the Event Thread to do its work.

4) Are you in fact getting any exceptions? If yes, please share the messages from them.

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
New Developer
Posts: 86
Registered: ‎01-20-2012
My Device: Bold Touch

Re: How to replace a bitmapField in the mainscreen?

1) yes I will look in to that

 

2) this code is in the background thread where I'm streaming images and this particular snippet is what I am using to update the UI. as i mentioned in my previous post. It was just a workaround that i did to update my UI by pushing the same screen on top because the invalidate did not work for me. the problem is that the background thread runs in parallel to the UI inside a loop which streams the images until I sign out of hte application.

 

3)  I've caught the exceptions it says the screen im trying to display is already displayed which is true because of the workaround i did inside the same loop i told about.

Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various

Re: How to replace a bitmapField in the mainscreen?

OK, so you are mixing some things you shouldn't. pushScreen is a one-time operation while bitmap creation and setBitmap are repeated ones. So here is a better approach:

 

1. Push the screen only once - at some initialization point, doesn't matter whether it is in the background thread or not and save the reference to it in some class member (you seem to have already done the latter). Start the background thread.

2. In your background thread's main loop, repeatedly perform the following actions:

  a) load the new image from where you are loading them (some web service, SD card, etc.)

  b) create a Bitmap from the resulting bytes

  c) invokeLater a Runnable with setBitmap, using the saved reference to the Screen (again, it seems that you have the latter nailed down). For this to work you'll have to either declare your Bitmap final or make it a class member.

 

Notice that 2.a and 2.b happen on the background thread itself and only 2.c uses the Event Thread. So your blocking (2.a) and time-consuming (2.b) operations don't block your UI.

 

Enjoy!

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
New Developer
Posts: 86
Registered: ‎01-20-2012
My Device: Bold Touch

Re: How to replace a bitmapField in the mainscreen?

Hi like u said i h ave done the same thing before as you said. but i tried it again now the code runs fine but never updates the screen. have a look at this snippet please

 

UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{	

try
{
cams = jp;
System.out.println("TrView.jpegByteying to set the images!!!");				
camView.bmpStream.setBitmap(bit);
System.out.println("Created Bitmap Image: " + camView.bmpStream);				
	
System.out.println("Image Display Success");
}
catch(IllegalArgumentException ex)
{
	System.out.println("Image Display Exception: " + ex.getMessage());
}
catch(Exception ex)
{
	System.out.println("Exceptionn while displaying images: " + ex.getMessage());					
}
}
});

 

Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various

Re: How to replace a bitmapField in the mainscreen?

This code looks much better than the previous attempts. It is the part 2.c from my previous message, right? I hope the rest is also implemented correctly.

 

So now it's time for you to debug the problem. Make sure that your camView screen is displayed. Connect the phone to the debugger and take a look at console output - you might see something you didn't quite expect there. Or you might find that you need some additional info to be logged - add that if it's the case.

 

Just to clarify: I don't see any problems with this last code, so it means you are missing something (probably something small) in other parts of your program. Take time to debug that.

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
New Developer
Posts: 86
Registered: ‎01-20-2012
My Device: Bold Touch

Re: How to replace a bitmapField in the mainscreen?

Yeah mate ive got this nailed down properly but still i cannot update my mainScreen. the codes properly running plus  all my debug logs look normal nothing.

Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various

Re: How to replace a bitmapField in the mainscreen?

Since you still don't see the images change, you must be missing something. Since we here are just developers like you (and don't work for RIM) we can't remotely debug your problem. Put in more effort, don't trust any line of code to do what you think it is doing, and debug, debug, debug. Make your code smaller but still meaningful and work from there. You say you succeeded with static images - slowly get from there to your full code and see at which point you lose the functionality. Whatever code you added between the two points has some problem. Concentrate your efforts there.

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!