Nativescript: make app suspend instead of exit

Created on 27 May 2017  路  5Comments  路  Source: NativeScript/NativeScript

my app creates a worker that keeps a connection open with the server and receives messages.

  • When the user navigates away from the app it gets suspended, which doesn't kill the worker and messages still arrive.

  • But when the user leaves pressing the back button, 90% of the times the app exits, the worker gets killed, connection to server cut and messages don't arrive anymore (I guess Android some times decides not to kill it, that's the other 10%).

Is there any cross-platform way to catch that back button event that would exit the app, and make it minimize, suspend instead?

In the long term Android will kill the app if the user doesn't interact with it again, and that's ok, I'm just interested in not killing it straight away because of the back button.

I see the application module has an AndroidActivityBackPressedEventData with a cancel property, but I can't find a way to generate the suspend event instead, and in a cross-platform manner.

android question

Most helpful comment

thanks @NickIliev , I managed to do the job mixing the ideas from a couple of those links.

Problem was: android's back button closes the app and its related resources (main thread and workers), for example any connection to a server that you'd like to keep open.
Idea: handle the back button event and make the app go to the home screen instead.

Code in case someone is looking for it:

app.js

var application = require("application");
var frame = require('ui/frame');

//if your page exports a function called backEvent, use it to handle BackPressedEvent
//otherwise normal behaviour

if (application.android) {
    application.android.on(application.AndroidApplication.activityBackPressedEvent, backEvent);
}
function backEvent(args) {
    var currentPage = frame.topmost().currentPage;
    if (currentPage && currentPage.exports && typeof currentPage.exports.backEvent === "function") {
         currentPage.exports.backEvent(args);
   }   
}

main_page.js

var application = require("application");
var frame = require("ui/frame");

exports.backEvent = function(args) {

    args.cancel = true;

    var startMain = new android.content.Intent(android.content.Intent.ACTION_MAIN);
    startMain.addCategory(android.content.Intent.CATEGORY_HOME);
    startMain.setFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);

    var activity = application.android.startActivity || application.android.foregroundActivity ||
        frame.topmost().android.currentActivity || frame.topmost().android.activity;
    activity.startActivity(startMain);
}

All 5 comments

@1u0n you can use the exposed cross-platform lifecycle events from the application module and also you can use the specific Android events like activityBackPressedEvent to overwrite the default logic only for Android.

There is also a few threads and blogs discussing how to handle the back button in NativeScript (Android) like this blog post , this SO thread and this code snack. I hipe one of the provided solutions would be applicable for you scenario.

thanks @NickIliev , I managed to do the job mixing the ideas from a couple of those links.

Problem was: android's back button closes the app and its related resources (main thread and workers), for example any connection to a server that you'd like to keep open.
Idea: handle the back button event and make the app go to the home screen instead.

Code in case someone is looking for it:

app.js

var application = require("application");
var frame = require('ui/frame');

//if your page exports a function called backEvent, use it to handle BackPressedEvent
//otherwise normal behaviour

if (application.android) {
    application.android.on(application.AndroidApplication.activityBackPressedEvent, backEvent);
}
function backEvent(args) {
    var currentPage = frame.topmost().currentPage;
    if (currentPage && currentPage.exports && typeof currentPage.exports.backEvent === "function") {
         currentPage.exports.backEvent(args);
   }   
}

main_page.js

var application = require("application");
var frame = require("ui/frame");

exports.backEvent = function(args) {

    args.cancel = true;

    var startMain = new android.content.Intent(android.content.Intent.ACTION_MAIN);
    startMain.addCategory(android.content.Intent.CATEGORY_HOME);
    startMain.setFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);

    var activity = application.android.startActivity || application.android.foregroundActivity ||
        frame.topmost().android.currentActivity || frame.topmost().android.activity;
    activity.startActivity(startMain);
}

how can we use this code with nativescript angular?

And also with nativescript vue?

@anandbaskaran , using @1u0n code I did like this on the 'mounted' section of my vue main component:

if (platform.isAndroid) {
    application.android.on(
        application.AndroidApplication.activityBackPressedEvent,
        data => {
          data.cancel = true

          if (this.BGAtivo) {
            var startMain = new android.content.Intent(
              android.content.Intent.ACTION_MAIN
            )
            startMain.addCategory(android.content.Intent.CATEGORY_HOME)
            startMain.setFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK)
            var activity =
              application.android.startActivity ||
              application.android.foregroundActivity ||
              frame.topmost().android.currentActivity ||
              frame.topmost().android.activity
            activity.startActivity(startMain)
          } else {
            android.os.Process.killProcess(android.os.Process.myPid())
          }
        }
    )
}

The "this.BGAtivo" is a local variable I made to indicate when there is a service running on background. The "android.os.Process.killProcess(android.os.Process.myPid())" here is used to
immediately close the application, preventing the previous page from being displayed. Which, in my case, is a login page. Hope it helps.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

valentinstoychev picture valentinstoychev  路  3Comments

nirsalon picture nirsalon  路  3Comments

dhanalakshmitawwa picture dhanalakshmitawwa  路  3Comments

rogangriffin picture rogangriffin  路  3Comments

rLoka picture rLoka  路  3Comments