Results 1 to 9 of 9
  1.    #1  
    I posted this on Palm's site but haven't gotten any hits. My apologies if you're following both sites.

    I have a background application ("noWindow" : "true") that uses an application assistant and at various times creates dashboard and card stages. It never pushes more than one scene on any stage. When I close the scenes by swiping them off the screen, I see their cleanup methods execute in the logs, but the app-assistant remains running in the background. That is to say, its cleanup method never runs and I see one handle remaining open in palm-worm. At this point in time, none of the assistants make any service requests of any kind, they're just displaying text on the view pages.

    What are the criteria for webOS to close a background application? Once all the scenes have been popped, I would expect their stages to close and then the application to close. Is that not correct? I've tried adding Mojo.Controller.appController.closeStage() and closeAllStages() calls, but that still doesn't seem to force the application closed.

    Actually, it's inconsistent, sometimes it closes but not usually. I can kill it manually with "palm-launch -c...".

    I'm quite confused by this and any help would be appreciated. I have searched high and low for the answers.
    "The service on my iPhone is so bad I'm thinking of calling it my AOL phone." -- Jim Gaffigan

  2. #2  
    It should close an app when all stages have been closed. The only other way an app stays running in the background is if you use the activityStart service to keep it running.

    If you need to force an app to close, you can call window.close() from the App Assistant.
  3.    #3  
    Thanks for the response. That's my understanding as well but something else seems to be going on.

    I am definitely not using activityStart. Is it possible my stages aren't closing when their respective scenes are closed? Not based on what I've read, but something is definitely happening. How else to explain the open handle?

    When would I use window.close? Can I listen for the stages to close and then call it?
    "The service on my iPhone is so bad I'm thinking of calling it my AOL phone." -- Jim Gaffigan

  4. #4  
    Quote Originally Posted by monkeydog View Post
    Thanks for the response. That's my understanding as well but something else seems to be going on.

    I am definitely not using activityStart. Is it possible my stages aren't closing when their respective scenes are closed? Not based on what I've read, but something is definitely happening. How else to explain the open handle?

    When would I use window.close? Can I listen for the stages to close and then call it?
    You really shouldn't have to call window.close() if you're not implicitly forcing your app to stay running in the background.

    Perhaps you have an exception somewhere that is preventing the app from fully closing. Also make sure all referenced objects, handlers, service requests etc. are released properly.
  5.    #5  
    DanPLC, thank you so much for your attention and patience. I appreciate it immensely.

    I have stripped my app down to the bare bones trying to find this. The code that follows opens a dashboard and displays a message. A tap on the dashboard opens a card. A subsequent launch updates the contents of the dashboard.

    When you swipe the various scenes away, their respective stages should close and the the AppAssistant.prototype.cleanup() method should execute, displaying a message in the log. However, something is forcing the application assistant to stay open so the message never displays. Looking at it in palm-worm shows one handle still open. Forcing the app closed with "palm-launch -c" causes the cleanup() method to execute, logs the message and closes the handle.

    The first one to find the bug gets my eternal respect and gratitude and a click of the "thanks" button. If you're a developer, I'll buy your app.

    162 lines of code follow:

    app-assistant.jsjsjs:
    Code:
    function AppAssistant() {
    }
    
    AppAssistant.prototype.cleanup = function() {
    	try {
    		Mojo.Log.error("Why doesn't this method ever run?!?");
    	} catch (e) {
    		Mojo.Log.error('AppAssistant.prototype.cleanup', e);
    	}
    }
    
    //-------------------------------------------------------
    //handleLaunch - called by the framework when the application is asked to launch
    AppAssistant.prototype.handleLaunch = function(launchParams) {
    	try {
    		var appController = Mojo.Controller.getAppController();
    		
    		if (!launchParams) {
    			// app was launched directly from the launcher
    			var dashboardStage = appController.getStageProxy('dashboardStage');
    			if (dashboardStage) {
    				dashboardStage.delegateToSceneAssistant('updateDashboard', 'Application relaunched', 'Dashboard contents replaced');
    			} else {
    				var pushDashboard = function(stageController){
    					stageController.pushScene('dashboard', 'New launch of application', 'New dashboard created');
    				};
    				appController.createStageWithCallback(
    					{
    						name: 'dashboardStage', 
    						lightweight: true, 
    						assistant: 'DashboardAssistant'
    					}, 
    					pushDashboard,
    					'dashboard'
    				);
    			}
    		} else {
    			// app was relaunched with a tap to the dashboard or some such
    			switch (launchParams.action) {
    				case 'dashboardTap': 
    					// look for card stage by name
    					var cardStageController = this.controller.getStageController('cardStage');
    					if (cardStageController) {
    						// if it exists, bring it to the front
    						cardStageController.popScenesTo('main');
    						cardStageController.activate();
    					} else {
    						// Create a callback function to set up the new card stage once it's done loading.
    						// It is passed the new stage controller as the first parameter.
    						var pushMainScene = function (stageController) {
    							stageController.pushScene('main', 'Dashboard tapped', 'Card stage created');
    						}
    						var stageArguments = {name: 'cardStage', lightweight: true};
    						this.controller.createStageWithCallback(stageArguments, pushMainScene.bind(this), 'card');
    					}
    					break;
    			}
    		}
    		
    	} catch (e) {
    		Mojo.Log.error('AppAssistant.prototype.handleLaunch', e);
    	}
    };
    dashboard-assistant.jsjsjs:
    Code:
    function DashboardAssistant(title, message) {
    	this.title = title;
    	this.message = message;
    }
    
    DashboardAssistant.prototype.setup = function() {
    	try {
    		this.tapHandler = this.launchMain.bindAsEventListener(this);
    		this.controller.listen("dashboardinfo", Mojo.Event.tap, this.tapHandler);
    	} catch (e) {
    		Mojo.Log.error("DashboardAssistant.prototype.setup", e);
    	}
    }
    
    DashboardAssistant.prototype.activate = function(event) {
    	try {
    		var updateDashboard = this.updateDashboard.bind(this);
    		updateDashboard(this.title, this.message);
    	} catch (e) {
    		Mojo.Log.error("DashboardAssistant.prototype.activate", e);
    	}
    }
    
    DashboardAssistant.prototype.cleanup = function(event) {
    	try {
    		this.controller.stopListening("dashboardinfo", Mojo.Event.tap, this.tapHandler);
    	} catch (e) {
    		Mojo.Log.error("DashboardAssistant.prototype.cleanup", e);
    	}
    }
    
    DashboardAssistant.prototype.updateDashboard = function(title, message) {
    	try {
    		var info = {
    			title:		title,
    			message:	message
    		};
    		var renderedInfo = Mojo.View.render( {
    			object:		info,
    			template:	'dashboard/dashboard-item'
    		});
    		var dashboard = this.controller.get('dashboardinfo');
    		dashboard.innerHTML = renderedInfo;
    	} catch (e) {
    		Mojo.Log.error("DashboardAssistant.prototype.updateDashboard", e);
    	}
    }
    
    DashboardAssistant.prototype.launchMain = function() {
    	try {
    		Mojo.Controller.getAppController().assistant.handleLaunch( {action: "dashboardTap"});
    	} catch (e) {
    		Mojo.Log.error("DashboardAssistant.prototype.launchMain", e);
    	}
    };
    main-assistant.jsjsjs:
    Code:
    function MainAssistant(title, message) {
    	this.title = title;
    	this.message = message;
    }
    
    MainAssistant.prototype.activate = function(event) {
    	try {
    		var updateCard = this.updateCard.bind(this);
    		updateCard(this.title, this.message);
    	} catch (e) {
    		Mojo.Log.error("MainAssistant.prototype.activate", e);
    	}
    }
    
    MainAssistant.prototype.updateCard = function(title, message) {
    	try {
    		var info = {
    			title:		title,
    			message:	message
    		};
    		var renderedInfo = Mojo.View.render( {
    			object:		info,
    			template:	'main/main-item'
    		});
    		var main = this.controller.get('maininfo');
    		main.innerHTML = renderedInfo;
    	} catch (e) {
    		Mojo.Log.error("MainAssistant.prototype.updateCard", e);
    	}
    }
    "The service on my iPhone is so bad I'm thinking of calling it my AOL phone." -- Jim Gaffigan

  6. #6  
    I wonder if this is a bug in WebOS. I notice the phone tends to get progressively slower as you run more apps and web browsers, and swipe them away. Eventually it gets slow enough that a Luna restart is needed to restore the normal snappiness.

    Maybe your code is right, but there's a problem with WebOS? Failure to clean up old resources would certainly explain the behavior I've seen.
  7.    #7  
    Quote Originally Posted by zorinlynx View Post
    I wonder if this is a bug in WebOS. I notice the phone tends to get progressively slower as you run more apps and web browsers, and swipe them away. Eventually it gets slow enough that a Luna restart is needed to restore the normal snappiness.

    Maybe your code is right, but there's a problem with WebOS? Failure to clean up old resources would certainly explain the behavior I've seen.
    Normally I would blame apps with memory leaks for the slowness you're seeing. That's why I've been diligent in trying to eradicate this one: I don't want my app to be the one that forces people to do restarts.

    To test your theory, I did do a restart and guess what? It worked! The app closes exactly like it's supposed to, with no changes to the above code. I wonder if the process of installing, re-installing, de-installing, deleting, and re-installing the same program somehow leaves traces of past versions in memory. When I forced JavaScript garbage collection using palm-worm it didn't clean it up, but the restart did.

    Thanks zorinlynx!
    "The service on my iPhone is so bad I'm thinking of calling it my AOL phone." -- Jim Gaffigan

  8. #8  
    Quote Originally Posted by monkeydog View Post
    To test your theory, I did do a restart and guess what? It worked! The app closes exactly like it's supposed to,...
    what are you using to close the app? window.close() or something else? i'm looking for a similar solution. thanks!
    My site: Shanerooni, LLC
    Follow me on Twitter
    My apps: GuessWhat? | MazeHunter3D | Small Wonders | PhakePhoney | AutismAware | PicSketcher | Cubix | QuickSolve | QuickSpell | QuickTrace | QuickWhack | QuickSuite | Soccer Shots | Ballooning |
    Cubix
  9. #9  
    Didn't wanna start a whole new thread...

    When I swipe the dashboard away and the app is still running in the background, relaunching it from the launcher shows a full card with a black background with the dashboard div at the top.

    Anyway to prevent that?

    I really hate the lack of material there is on the SDK. I would love some more advanced tutorials. PHP was much easier to jump into!

Posting Permissions