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: 44
Registered: ‎08-06-2009
My Device: Not Specified
Accepted Solution

UiApplication - put into RuntimeStore vs make Singleton Object / Instance

[ Edited ]

Hello all,

 

I have run into lots of trouble with putting the UiApplication instance into the RuntimeStore for later retrieval from alternate entry points etc.  I have used the code from this resource (http://supportforums.blackberry.com/t5/Java-Development/Make-a-running-UI-application-go-to-the-back...)

 

 

//register the alternate on first run
RuntimeStore appReg = RuntimeStore.getRuntimeStore();
synchronized(appReg){
   if (appReg.get(ID) == null) {
       appReg.put(ID, new Application(...));
   }
   Application MyApp = (Application)appReg.waitFor(ID);
   //then you have the app MyApp... return it or whatever
}

 

//check to see if the app exists, if it does, bring it to the foreground ...
RuntimeStore appReg = RuntimeStore.getRuntimeStore();
synchronized(appReg){
if (appReg.get(ID) != null){
Application MyApp = (Application)appReg.waitFor(ID);
MyApp.requestForground();
}
}

 

but UiApplication.getUiApplicationInstance(); returns an IllegalStateException.

 

I have posted this before and have read that I might be better off creating a Singleton instance of my UiApplication - can I get some pointers to how to accomplish this?  The code I think I should be referencing is:

 

 

import net.rim.device.api.system.*;

class MySingleton {
   private static MySingleton _instance;
   private static final long GUID = 0xab4dd61c5d004c18L;

   // constructor
   MySingleton() {}

   public static MySingleton getInstance() {
      if (_instance == null) {
         _instance = (MySingleton)RuntimeStore.getRuntimeStore().get(GUID);
      if (_instance == null) {

         MySingleton singleton = new MySingleton();

         RuntimeStore.getRuntimeStore().put(GUID, singleton);
         _instance = singleton;
         }
      }

      return _instance;

   }
}

 Thank you in advance for any help.

 

Developer
Posts: 19,631
Registered: ‎07-14-2008
My Device: Not Specified

Re: UiApplication - put into RuntimeStore vs make Singleton Object / Instance

I would caution against putting your Application into RuntimeStore.  Unless you are very careful, this will mean that your application will always be in memory on the BlackBerry - System.exit() does not remove RuntimeStore.  Try to find another way around your problem if you can.

 

In addition, Alternate Entries are often mis-used by people, in fact there are some circumstances where it is better NOT to use an Alternate Entry, though people will still tell you to use one. 

 

So please can we understand what you are trying to do and rather than trying to fix this code, we might be able to suggest a better solution. 

Developer
Posts: 16,750
Registered: ‎07-29-2008
My Device: Z10 LE, Z30, Passport
My Carrier: O2 Germany

Re: UiApplication - put into RuntimeStore vs make Singleton Object / Instance

I completely agree with peter. it is possible to put a whole app into the runtime store, but it really opens a lot of unnecessary problems.

I use the runtimestore for several services I share between apps or entry points, but never for a whole app.

----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
New Developer
Posts: 44
Registered: ‎08-06-2009
My Device: Not Specified

Re: UiApplication - put into RuntimeStore vs make Singleton Object / Instance

[ Edited ]

Thank you both for your input.  You have replied to many of my other threads and have shared many insights on this board.

 

I have tried this two ways: 1. using the alternate entry point and 2. autostarting my UiApplication without an alternate entry point

 

What I need to do it / am doing:

1. alternate

<upon device bootup> I will initialize my UiApplication (screen does not need to be shown) and will register various listeners (phone, message, key etc) and saving the static instance of the UiApplication in the RuntimeStore

<upon launching from icon>

the RuntimeStore is checked to see if the application exists.  If it does not exist create an instance, if it exists get the RuntimeStore object and cast it to UiApplication and create a static instance

 

all this works fine.  I use the staic instance of the UiApplication within the main method and everywhere else I use UiApplication.getApplication() to access the UiApplication.  so all works

	public static void main(String[] a)
	{
		long runID= 0x******;
		RuntimeStore alphaRun= RuntimeStore.getRuntimeStore();
		if (a!=null && a.length > 0 && a[0].equals("startup"))
		{
			adison= new AdisonAlpha(false);
			if(ApplicationManager.getApplicationManager().inStartup())
			{
				UiApplication.getUiApplication().addSystemListener(adison);
			}
			else
			{
				adison.initialize();
			}
			synchronized(alphaRun)
			{
				alphaRun.put(runID, adison);
			}
			adison.enterEventDispatcher();
		}
		else
		{
			Object bowl;
			synchronized(alphaRun)
			{
				bowl= alphaRun.get(runID);
			}
			if(bowl==null)
			{
				adison= new AdisonAlpha(true);
				adison.initialize();
				synchronized(alphaRun)
				{
					alphaRun.put(runID, adison);
				}
				adison.enterEventDispatcher();
			}
			else
			{
				adison= (AdisonAlpha)alphaRun.get(runID);
				adison.requestForeground();
			}
		}
	}
	public AdisonAlpha(boolean screen){
		mainScreen= new AdisonScreen();
		UiApplication.getUiApplication().pushScreen(mainScreen);
		if(!screen)
		{
		}
		else
		{
		}
	}
	private void initialize()
	{
		Bitmap launchLogo= Bitmap.getBitmapResource("Off3D3232.png");
		Bitmap updateLaunchLogo= Bitmap.getBitmapResource("On3D3232.png");
		HomeScreen.updateIcon(launchLogo,0);
		HomeScreen.setRolloverIcon(updateLaunchLogo,0);	
	}
	public void batteryGood() {}
	public void batteryLow() {}
	public void batteryStatusChange(int status) {}
	public void powerOff() {}
	public void powerUp() 
	{
		initialize();
	}
	class AdisonScreen extends FullScreen{
		public AdisonScreen(){
			super(DEFAULT_CLOSE|DEFAULT_MENU);
			add(new LabelField("™"));
		}
		public boolean onClose()  // this is called when 'back button' is hit to close
		{
			UiApplication.getUiApplication().requestBackground();
			return true;
		}
		protected void makeMenu(Menu menu, int instance)
		{
			menu.add(exit);
		}
		private MenuItem exit = new MenuItem("exit", 110, 10)
		{
			public void run()
			{
				long runID= 0x96c8a0c9043f66bcL;
				RuntimeStore alphaRun= RuntimeStore.getRuntimeStore();
				synchronized(alphaRun)
				{
					alphaRun.remove(runID);
				}
				mainScreen.close();
				UiApplication.getUiApplication().popScreen(mainScreen);
			}
		};
	}
}

 

except when I terminate the application and relaunch it, non of the code in the static void main method is called although the application initializes (the screen shows the way it is supposed to show).

 

 

 

2. autostarting the application (setting it to autostart but not 'system module' in the eclipse project settings), the application initializes fine, but when I try to launch the application using the icon, there is no response and the OS freezes up until I press the 'red call end' button. How can I prevent the app from freesing up?

 

 

public class AdisonAlphaStart extends UiApplication implements SystemListener
{
	public static void main(String[] a)
	{
		long runID= 0xd7b***;
		RuntimeStore alphaRun= RuntimeStore.getRuntimeStore();
		synchronized(alphaRun)
		{
			if(alphaRun.get(runID)==null)
			{
				if(ApplicationManager.getApplicationManager().inStartup())  // if need to delay
				{
					AdisonAlphaStart alphaInstance= new AdisonAlphaStart();
					UiApplication.getUiApplication().addSystemListener(alphaInstance);
					alphaInstance.enterEventDispatcher();  
				}
			}
			else  //instance exists so not starting up
			{
				AdisonAlphaStart alphaInstance;
				alphaInstance= (AdisonAlphaStart) alphaRun.get(runID);
			}
		}
		
		
	}
	private void appInitialize()
	{
		long runID= 0xd****0L;
		RuntimeStore alphaRun= RuntimeStore.getRuntimeStore();
		/*synchronized(alphaRun)
		{
			alphaRun.put(runID, UiApplication.getUiApplication());
		}*/
		Bitmap launchLogo= Bitmap.getBitmapResource("Off3D3232.png");
		Bitmap updateLaunchLogo= Bitmap.getBitmapResource("On3D3232.png");
		HomeScreen.updateIcon(launchLogo,0);
		HomeScreen.setRolloverIcon(updateLaunchLogo,0);	
		
	}
	public AdisonAlphaStart()
	{
	}
	public void batteryGood() {}
	public void batteryLow() {}
	public void batteryStatusChange(int status) {}
	public void powerOff() {}
	public void powerUp()
	{
		appInitialize();
	}
}

I basically need to initialize (listeners etc) whenever the app starts and until the program terminates, it should access the RuntimeStore to retrive the UiApplication instance.  If it is terminated it shoud create a new UiApplication and replace the existing RuntimeStore for later access.

 

Back to debugging,

Thank you again for any help!

Developer
Posts: 19,631
Registered: ‎07-14-2008
My Device: Not Specified

Re: UiApplication - put into RuntimeStore vs make Singleton Object / Instance

Sorry, I have not looked at your code in detail.  Both Simon and I wanted to understand what your application was trying to do, rather than how it was doing it.

 

From what you have described so far, you do not need to put your UiApplication into RuntimeStore.  Nor do you need an AlternateEntry.

 

So let us try to see if we can get your Application working the way you want without do these.  I'm not saying we will succeed, but by trying, we and you will understand the possibilities better.

 

But note that this is only my opinion and here is how I would implement what you are trying to do, with a single application. I could be missing something. 

 

Let us start first with the listeners.

 

Some listeners require that there be an application present - for example SystemListener.  Some do not, for example the phone listeners.  Some processing is retained over a soft reset - for example, most non networking Threads will be paused and restarted.  Some are not, for example, ApplicationMenuItems are removed. 

 

Let us assume that at least one of your listeners requires an Application.  I typically do use an Application, because I will use SystemListener so that I can terminate all my processing as part of powerOff, and restart it as part of powerUp.  So that means you must have an Application that is auto-started. 

 

Now you also want to have an icon.  Since an icon expects to start a UiApplication, then let us make your autostarted Application a UiApplication.  To make this work, it really needs to push a Screen, but it can also 'requestBackground()', so that it does not actually display during autostart.

 

The complication here is that some of this processing can't actually be performed at the early stages of start-up, so you have to check for

ApplicationManager......inStartUp()

and process accordingly.  There is a KB article that describes this I think.

 

So now we have an autostarted UiApplication, that listens for system startup and shutdown, and stops everything on shutdown and starts everything on startup. 

 

Now when you click on the icon, you are not actually starting your application, you are just foregrounding an existing UiApplication. 

 

I think so far we have matched your requirements with one exception.  What if you want to restart your Application?

 

We have already described code that shuts-down your Application processing - we will run this in powerOff.  You just need to run that, and then do a System.exit().  Now when your main is invoked, the next time the user clicks on your icon, it will started just like it is during auto-start, and so will go through the same initialization.  The trick is this time, you do not want to do the requestBackground.

 

So here are the key parts.

 

1) An initialization routine that adds the listeners and starts other processing.  This will also push the initial screen. 

 

2) A termination routine that stops all the processing started in the initialization routine

 

3) main routine creates the UiApplication and adds it as a SystemListener and enterTheDisplatcher.  It checks to see if the processing is inStartUp. 

a) If so, it backgrounds the application - the initialization will be done by SystemListener powerUp.

b) If not, it runs the initialization routine

 

4) SystemListener powerUp routine, which runs the initialization routine

 

5) SystemListener powerOff routine that runs the termination routine

 

6) Exit processing in your application that runs the termination routine and then calls System.exit(). 

 

I think if you implement these parts you will have an applciation that processes the way you want, with no RuntimeStorage and no AlternateEntry. 

 

New Developer
Posts: 44
Registered: ‎08-06-2009
My Device: Not Specified

Re: UiApplication - put into RuntimeStore vs make Singleton Object / Instance

[ Edited ]

Thank you for your follow up. 

 

The problem I am having with autostarting the UiApplication (NO System module, YES Auto-run on startup) is that when I click on the application icon, the OS freezes up until I press the Red / Cancel call button.  I do not define Argument passed to "static public void main" and within this method I immediately check for if the UiApplication is null or not.

How can I prevent freezing upon launching the UiApplication from the icon?

 

edited: I was having the above problem because upon reentry there was no screen to display (had not pushed a screen).

 

On issue I am having is that upon re-entry, the "static public void main" is not accessed.  I am calling UiApplication.getApplication().requestForeground() and the screen is showing fine, but no breakpoints are being hit.  From the screen if I call menu functions, there are breakpoints that are hit, so it is just the "static public void main"method that is not acting as expected. 

Developer
Posts: 19,631
Registered: ‎07-14-2008
My Device: Not Specified

Re: UiApplication - put into RuntimeStore vs make Singleton Object / Instance

I'm guessing the freezing you are seeing is not actually freezing - it is just that whatever application you have started does not have a screen pushed. 

 

You should see this on the Simulator.  the log should tell you if you are starting another Application or foregrounding an existing application.  If you use the approach I have outlined above, you will be foregrounding the autostarted UiApplication and so it should display the screen you have pushed. 

 

However in this case, I think you are trying to do something clever with aa application you are retrieving from RuntimeStore.  As noted, I don't think you should do that unless there is no other choice.  Rather than attempting to fix this, I would try to change your startup processing to match what I have described. 

New Developer
Posts: 44
Registered: ‎08-06-2009
My Device: Not Specified

Re: UiApplication - put into RuntimeStore vs make Singleton Object / Instance

Thank you again Peter.  I forgot to mention that I have forgone using the RuntimeStore as your have mentioned.  The problem I am having now is that upon re-entry (i.e there is an instance of the UiApplication) to the UiApplication from the icon, the main method is not being called.  I am fiddling around with non auto-started alternateive entry point, but this does not seem to be working.  The app is responding to other method calls - just no the main method when launched from the icon. 

Developer
Posts: 19,631
Registered: ‎07-14-2008
My Device: Not Specified

Re: UiApplication - put into RuntimeStore vs make Singleton Object / Instance

As noted above, main will not be used if the application is already active and so the icon processing just foregrounds it. 

 

With applications like this, I usually have two possible exit methods

a) Close - which just puts the application into the background and does not pop the screen.

b) Exit, which does a System .exit()

 

Is it possible in your case that you pop the last screen after your user has tried the application?

 

Also as noted above, an Alternate Entry Point should not be needed in your case. 

Highlighted
New Developer
Posts: 44
Registered: ‎08-06-2009
My Device: Not Specified

Re: UiApplication - put into RuntimeStore vs make Singleton Object / Instance

Thank you again for your solution.

 

I was able to solve the problem both ways.  I will be back for more help later =).