Titanium Mobile Android: Memory not released when app is closed - titanium

We have developed an app using Titanium Mobile. When we first run the app in an Android device it uses around 25MB of memory. But every time we exit the app by using the device back button and then relaunch the app, the memory usage goes up by 10MB. So if we exit and relaunch the app 5 times, the app ends up using 50MB of extra memory, for a total usage of 75MB. If we launch the app a few more times, the app will simply not start, and the following error is thrown:
Uncaught Error: Failed to load resource, Java exception was thrwon.
Source = assets.readAsset(assetPath);
We initially thought it was a problem of our app, so we develop a simple app to test the issue. This test app just creates a window and adds a label to it. The app.js is the following:
function createView() {
var win1 = Titanium.UI.createWindow({
title:'Tab 1',
backgroundColor:'#fff',
exitOnClose: true
});
var label1 = Titanium.UI.createLabel({
color:'#999',
text:'I am Window 1',
font:{fontSize:20,fontFamily:'Helvetica Neue'},
textAlign:'center',
width:'auto'
});
win1.add(label1);
win1.open();
}
createView();
Well, the test app has the same problem as our original app. The first time it is launched it consumes 14MB of memory. After 5 restarts (using the device back button) it is consuming 21MB (150% of the inital memory).
We have also tried the sample app that is generated when you create a project in Titanium and the Kitchen Sink app developed by Titanium. The results are the same.
Our tests are done using Titanium 3.0.0.GA with two different devices:
HTC Desire Z - Android 2.3
Samsung Galaxy 2 - Android 4.0
We have searched for a solution to this problem with no results. We do not want to believe this is the normal behaviour of Titanium, because if so, Titanium is simply not an option for us. Has anyone found any solution/workaround for this issue?
Thanks in advance
UPDATE: added tiapp.xml of test app
<?xml version="1.0" encoding="UTF-8"?>
<ti:app xmlns:ti="http://ti.appcelerator.org">
<id>com.cloudship.titanium.mobile.test</id>
<name>titanium-mobile-test</name>
<version>1.0</version>
<publisher>Javier</publisher>
<url>http://</url>
<description>not specified</description>
<copyright>2013 by Javier</copyright>
<icon>appicon.png</icon>
<persistent-wifi>false</persistent-wifi>
<prerendered-icon>false</prerendered-icon>
<statusbar-style>default</statusbar-style>
<statusbar-hidden>false</statusbar-hidden>
<fullscreen>false</fullscreen>
<navbar-hidden>true</navbar-hidden>
<analytics>true</analytics>
<guid>18e506f3-02d4-4fb7-84b7-ff8d4c1fac82</guid>
<property name="ti.ui.defaultunit" type="string">system</property>
<iphone>
<orientations device="iphone">
<orientation>Ti.UI.PORTRAIT</orientation>
</orientations>
<orientations device="ipad">
<orientation>Ti.UI.PORTRAIT</orientation>
<orientation>Ti.UI.UPSIDE_PORTRAIT</orientation>
<orientation>Ti.UI.LANDSCAPE_LEFT</orientation>
<orientation>Ti.UI.LANDSCAPE_RIGHT</orientation>
</orientations>
</iphone>
<android xmlns:android="http://schemas.android.com/apk/res/android">
<manifest>
<application android:debuggable="true"/>
<supports-screens android:anyDensity="true"/>
</manifest>
</android>
<mobileweb>
<precache/>
<splash>
<enabled>true</enabled>
<inline-css-images>true</inline-css-images>
</splash>
<theme>default</theme>
</mobileweb>
<modules/>
<deployment-targets>
<target device="iphone">false</target>
<target device="ipad">false</target>
<target device="blackberry">false</target>
<target device="android">true</target>
<target device="mobileweb">false</target>
</deployment-targets>
<sdk-version>3.0.0.GA</sdk-version>
</ti:app>

It is a bug in Titanium 3.0.0.GA. See jira ticket here. Fortunately it has been fixed in 3.0.2.
Answer was given in Titanium Q&A

i'm also developing Titanium. I checked my app and I'm not experiencing this problems on Android 2.2.2 on an HTC Desire. The app is closed correctly.
Can you test with the following code:
var win1 = Titanium.UI.createWindow({
title:'Tab 1',
backgroundColor:'#fff',
exitOnClose: true
});
var label1 = Titanium.UI.createLabel({
color:'#999',
text:'I am Window 1',
font:{fontSize:20,fontFamily:'Helvetica Neue'},
textAlign:'center',
width:'auto'
});
win1.add(label1);
win1.open();
so remove the surrounding function.

this is solution to memory woes..please go through this thread
https://developer.appcelerator.com/question/116867/this-is-a-solution-to-your-memory-woes

Related

App doesn't run correctly from ToastNotification action

I'm trying to make a very simple demo to show how to work with Background Tasks and Toast Notifications in UWP. I've a simple task, which is triggered on network connection change and his work is to show a simple notification. It's of course registered in OS, selected in manifest and this task works well.
I've created a package and installed the app in my laptop to try if it run even in the moment when the app isn't launched. Task works as well.
The only problem is, that when I click on "Run app" button in notification, I want to launch app running in foreground. It starts app, but the only thing I can see is splash screen of my app and nothing else happened. I saw MSDN tutorial to this notification and my XML is almost the same.
My XML notification's content:
<toast launch="app-defined-string">
<visual>
<binding template="ToastGeneric">
<text>Test notification</text>
<text>This is a simple toast notification</text>
<image placement="AppLogoOverride" src="../Assets/icon.png"/>
</binding>
</visual>
<actions>
<action activationType="foreground" content="Run App" arguments="check" />
</actions>
<audio src="ms-winsoundevent:Notification.SMS" />
</toast>
UPDATE
The only modified part in App.xaml.cs:
protected override void OnActivated(IActivatedEventArgs args)
{
if (args.Kind == ActivationKind.ToastNotification)
{
var toastArgs = (ToastNotificationActivatedEventArgs)args;
ToastArg = toastArgs.Argument;
}
}
You need to invoke the initialization of your app (things inside OnLaunch method) from OnActivated. Remember to check if your app is running or not when initialization.

Worklight showIOS7StatusBar

I am running the Worklight IDE Version 6.0.0.20130926-1933. I have tried disabling the ios7 top status bar as per the Worklight technote found here:
http://www-01.ibm.com/support/docview.wss?uid=swg27039574
I have set in the initOptions.js file
var wlInitOptions = {
// # Should application automatically attempt to connect to Worklight Server on application start up
// # The default value is true, we are overriding it to false here.
connectOnStartup : true,
showIOS7StatusBar : false,
However, when I load my app I still see the statusBar displayed on my iOS7 devices. Is there some other change I need to make to my code? Note: I don't have access to xCode and I am using a company tool to build the ipa file. Thanks!
JT
You can also change it in the {AppName}-Info.plist in your IOS native directory
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIStatusBarHidden</key>
<true/>
Did you do a build of the application in Worklight and in Xcode and you still see it?
Anyway, you can add to your CSS file:
#wl_ios7bar {
display:none;
}
and you will not see it anymore.
What you can do is in the main.css or equivalent file of the iPhone environment specifically, override the application css with the code like:
.ios7
{
margin-top: 17px !important;
}
And in the main.js or equivalent file of the iPhone environment,
override the js file with the code like:
function wlEnvInit(){
wlCommonInit(); // Environment initialization code goes here
if (parseFloat(window.device.version) >= 7.0) {
$("body").addClass("ios7");
}
}
You can also check the reference link

worklight fail to require DOJO Combobox on real device -fail to load ... /dijit/form/nls/it/ComboBox.js

Dojo 1.8
Worklight 5.0.6
On Browser and android emulator all works, but if I execute the app on real the parse didn't works.
This is Dojo.js
function dojoInit() {
require([ "dojo",
"dojo/parser", "dojox/mobile", "dojox/mobile/compat",
"dojox/mobile/ScrollableView",
"dojox/mobile/ScreenSizeAware",
"dojox/mobile/FixedSplitter",
"dojox/mobile/Container",
"dojox/mobile/ComboBox"
],
function(dojo) {
dojo.ready(function() {
});
});
}
This is browser's error on tablet:
xxx.26.81:8080/apps /services/preview/AcgTablet/common/0/default/dijit/form/nls/it/ComboBox.js Error dojo.js:26
but this error doesn't appear on pc browser
But there are in the folder!
You are probably using Worklight V6?
There is an issue currently to run on Android devices. You can find the workaround here: Worklight core-web-layer.js errors
For your issue with running on Android, if you're using Worklight 6.0 with a new project, copy the following files from the Dojo Library project that was created alongside the Worklight project:
toolkit/dojo/dojo/nls/core-web-layer_ROOT.js
toolkit/dojo/dojo/nls/mobile-ui-layer_ROOT.js
These files then must be added to your Worklight project's www/dojo/nls/ directory.
In addition to including the *_ROOT.js files, you may also need to remove the development configuration from the application. To do this, open the Console view (Window > Show View > Other... > Console). From the Console view, click the Open Console button and choose Dojo Library Requests from the list. From the Dojo Library Requests console, click the View Menu (the triangle in the toolbar), and uncheck Provide Library Resources. After this, build and deploy your application to your emulator or device.
have you try doing it this way?
function dojoInit() {
require(["dojo/ready",
"dojox/mobile/parser",
"dojox/mobile",
"dojox/mobile/compat",
"dojox/mobile/ScrollableView",
"dojox/mobile/ScreenSizeAware",
"dojox/mobile/FixedSplitter",
"dojox/mobile/Container",
"dojox/mobile/ComboBox",
"dojo/ready!"
],
function(ready,parser,Container,ComboBox) {
ready(function() {
alert("I was clicked");
});
// Parse the page for widgets!
parser.parse();
});
Regards

Android InAppBrowser events not firing in phonegap-build

Im loading an external page with InAppBrowser and it seems like neither loadstart nor loadstop are been fired on Android. My code:
var ref = window.open(url, '_blank', 'location=yes;');
ref.addEventListener('loadstart', function() {
console.log('loadstart!');
console.log(event.url);
});
A couple of checks should fix it for you.
Make sure you load the right cordova-2.x.x.js file
// Platform: android
Include the InAppBrowser plugin in res/xml/config.xml
<plugin name="InAppBrowser" value="org.apache.cordova.InAppBrowser" />
Write the correct white-list tag (differs from iOS)
<access origin="https://domain.com" subdomains="true" />
You really have to include onDeviceReady like in the example files, that did the trick for me.
document.addEventListener('deviceready', app.onDeviceReady, false);

Titanium Appcelerator: How to set focus to the application window?

What is the Titanium method that shifts application focus to the Titanium app when an event occurs? For example, my application is constantly running in the background, and I want a window to open when email arrives.
You would like the Ti App to open when you receive an email on the device?
As far as I know, this won't happen automatically (as I could see many developers abusing this).
However, what I suggest is, add a URI Scheme (a url link or button) in the Email something like:
yourApp://view?id=abc which the user can click on, and it will open your app, and open the window/view/controller within your App. To do so, you will need to add URI schemes to your App, and handle the url, parse it, and so something useful with it in your App... here's how:
In the App's tiapp.xml, add this for iOS:
<dict>
<key>CFBundleURLName</key>
<!-- same as ti:app/id -->
<string>your.app.id</string>
<key>CFBundleURLSchemes</key>
<array>
<!-- your custom scheme -->
<string>yourApp</string>
</array>
</dict>
On Android in tiapp.xml in manifest node:
<application>
<activity android:configChanges="keyboardHidden|orientation" android:label="Your App"
android:name=".MyAppActivity" android:theme="#style/Theme.Titanium"
android:launchMode="singleTask" >
<!-- add the above launchMode attribute -->
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!-- add the below additional intent-filter -->
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="yourApp" />
</intent-filter>
</activity>
</application>
In Alloy.js:
if (OS_ANDROID) {
// Somehow, only in alloy.js we can get the data (URL) that opened the app
Alloy.Globals.url = Ti.Android.currentActivity.intent.data;
}
In your Main app.js or index.js:
// We don't want our URL to do anything before our main window is open
$.index.addEventListener('open', function (e) {
if (OS_IOS) {
// Handle the URL in case it opened the app
handleURL(Ti.App.getArguments().url);
// Handle the URL in case it resumed the app
Ti.App.addEventListener('resumed', function () {
handleURL(Ti.App.getArguments().url);
});
} else if (OS_ANDROID) {
// On Android, somehow the app always opens as new
handleURL(Alloy.globals.url);
}
});
var XCallbackURL = require('XCallbackURL');
function handleUrl(url) {
var URL = XCallbackURL.parse(url),
controller = URL.action(),
args = URL.params();
// Add some better logic here ;)
Alloy.createController(controller, args || {}).getView().open();
}
You can also learn more in much more details here: http://fokkezb.nl/2013/08/26/url-schemes-for-ios-and-android-1/
win.addEventListener('focus',function() {
// your code here
}
you can use setTimeOut() of javascript which will start another activity once your email popup or view or window does show up.
There are some issues with your example code:
You cannot handle incoming emails with your application (at least not in iOS). It is restricted by the iOS in order to ensure user privacy
The URL-schemes are used to handle links to your app (e.g. myapp:// from the browser or other apps)
In order to handle URL-schemes, use the handleurl event that is available in Titanium SDK 5.5.0.GA and later
Ensure that you remove event-listeners after leaving the current context, especially when you add event listeners in the open / focus event
If you follow that rules, you should be able to receive and handle URL's regarding your app, thanks!