Background/Foreground service in react native using Headless JS - javascript

I am using Headless JS in react native to create background service. My requirement is to create a service which will be invoked from MainActivity (For example on click of a button) and continue to execute even after the App goes to background. I could manage to create the service with Headless JS and invoke on button click. For simplicity I will explain with simple code
MyTask.js
module.exports = async () => {
console.log("I am called from java service");
for(var i=0; i<1000000;i++){
console.log("I am called from for loop"+i);
}
};
When using the above code, even after the app goes to background the for loop continues execution till i reaches 999999 also I am able to see the log message in console.
But my actual Task contains some async functions. For example when I use the following code in my task, it fails to print when the app goes to background
module.exports = async () => {
console.log("I am called from java service");
setInterval(() => {
console.log("I am called from java service inside setInterval");
}, 100);
};
The above code is supposed to print the log message continuously in 100 ms intervals. But the moment the app goes to background it stops printing. Again when the app resumes, it start printing again.
Can someone help on this?

My guess is that your activity is paused once your async headless task is over (from the caller perspective), this is what RN documentation suggests :
You can do anything in your task such as network requests, timers and
so on, as long as it doesn't touch UI. Once your task completes (i.e.
the promise is resolved), React Native will go into "paused" mode
(unless there are other tasks running, or there is a foreground app).
Although it's unclear, as you might think that JS timers - like setInterval would keep your code running... They won't.
The solution implied by RN doc is to implement a native service - for example a native timer instead of a JS one - which is basically what react-native-background-timer does...
EDIT
Regarding foreground execution, by default, headlessJS tasks are not allowed in foreground and will raise an error.

Related

The Electron app.isReady() function always false?

I have an electron app, it goes through a couple of files before creating the first window. But when it gets to the file that should create the window I checked and it is simply never ready. I am getting the error for creating a window before the app is ready but it's not a matter of time it really is just never ready.
I even put a while loop to while the app isn't ready and it never ends, I then moved it to the very first line of the first file (after requiring the app module) and it still got stuck and I have no idea why.
There really isn't any code to see here, it just the first line of the program there is nothing in the code that can affect it
The way you're checking the app readiness inside the loop isn't required at all. You can use the ready event as given in official docs or you can use the whenReady method which returns a promise to check the app is ready.
...
app.on('ready', () => {
...
...
});
//or
app.whenReady().then(() => {
...
});
Here is the example of using the whenReady.

How to call a function in WebView Javascript from Android Java without delay?

When using this method to call javascript functions there is a few millisecond delay (10ms - 50ms) in callback
webView.evaluateJavascript("javascript: updateARObject()", callback);
How to call a function instantaneously in javascript, all files are in asset folder of Android.
Is it possible with some custom WebView like Xwalkview?
Or socket connection between both?
ARCore is communicating with Three.js in real time, How to achieve that?
The reason the callback is present is because it cannot be done instantaneously from android app.
The main reason for that is that Android uses WebView to run javascript. Modern Android WebView is just an instance of Google Chrome wrapped in android view. As you understand this instance needs to be run on separate process as it does. If one chooses to dig deep he will find out that the communication between android app and WebView is done via AIDL service as all the interprocess communications should be done in android.
Taking into consideration the time needed to write an AIDL call into stack allocate memory and form message(main AIDL method of communication), send it, unwrap in Chrome, parse, execute javascript and do all this operations one more in order to answer - 10ms - 50ms is very low latency.
Maybe ArCore has its own its own js processor to handle js files fast. Or Google Chrome has its own method to communicate with ArCore(or inner instance). I don't know that - but it is Google developed products - I think they know their shortcuts.
Custom WebView may work - the only thing is that basically it will be a new version of browser you will need to support your js for it separately from all the other browsers due to a whole bunch of possible reasons.
Hope it helps you somehow.
From kitkat onwards use evaluateJavascript method instead loadUrl to call the javascript functions like below :
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
webView.evaluateJavascript("enable();", null);
} else {
webView.loadUrl("javascript:enable();");
}
you can Use function call delay by setting :
window.setTimeout(function () { ... })
But ,It won't necessarily run right away, neither will explicitly setting the delay. If you will use setTimeout, it removes the function from the execution queue and it will only be invoked after JavaScript has finished with the current execution queue.
console.log(1);
setTimeout(function() {console.log(2)});
console.log(3);
console.log(4);
console.log(5);
//console logs 1,3,4,5,2
for more details see http://javascriptweblog.wordpress.com/2010/06/28/understanding-javascript-timers/
Hope, you'll find your answer. Cheers!

How to call Java methods in React Native before startReactApplication has been called

In our Android app, I initialize the React Native JS code as soon as possible, because I have some JS code running in the background, even when no React Native views are currently visible. I do this by calling ReactInstanceManager#createReactContextInBackground().
This works, and the JS code gets initialized, but it appears I cannot call any Java methods annotated with #ReactMethod until I have actually opened a React Native view that calls ReactRootView#startReactApplication(). If I attempt to call any native methods before that, nothing happens, but it seems the calls get added to a queue and then eventually get picked up when the React view opens.
It appears the same thing goes for timers set with setTimeout(). They just don't get called when no view is open yet. So it seems the JS gets evaluated, but then the JS engine isn't "running" yet.
How can I make sure the engine is properly running before opening any React views?
Let your first RN View call a #ReactMethod that will set a flag in Java. Have your Java code not execute anything until the flag is set.

Javascript: How to write a function that will be executed asynchronously?

I have a few lines of code that I want to run asynchronously in Javascript so that it doesn't slow down my main algorithm. See this pseudo code:
//main algorithm with critical code that should run as soon as possible
...
...
runInParallel(function(){
//time consuming unimportant code to shows some progress feedback to user
...
}
//the rest of the time critical algorithm
...
...
runInParallel(function(){
//time consuming unimportant code to shows some progress feedback to user
...
}
//and so on and so forth
I searched Stackoverflow for how to write asynchronous code in Javascript but the following questions are not similar to mine:
how to run a javascript function asynchronously, without using setTimeout?: it's about server side
Loading javascript asynchronously - How to do callbacks?: it's about loading source code
I guess I can use timers for this purpose. All I want is the body of the function runInParallel() that runs a code efficiently in parallel with my main algorithm with lower priority if possible. Anyone?
Javascript has no synchronization / thread management. If you wish to execute something asynchronously, you can use setTimeout combined with a callback to be notified when the function 's finished.
var asyncHandle = setTimeout(function () { asyncCode(); callback(); }, 10);
The asyncHandle can be used to cancel the timeout prior to the function being called.
If you're targeting HTML5 supporting browsers, go with HTML5 Web Workers.
You can also try this interesting, but quite old JavaScript compiler that allows a language extension for this purpose.

jQuery profiling - measure complete onReady runtime

I'd like to measure how long it takes to run the whole $().ready() scope in each of page.
For profiling specific functions I just set a new Date() variable at the beginning of the relevant part and then check how long it takes to get to the end of the relevant part.
The problem with measuring the whole $().ready scope is that it can sometimes run some of the code asynchronously and then I can not wait for it all to finish and see how long it has taken.
Is there any event which is fired once the page has completely finished running all $().ready code?
EDIT: Using Firebug or other client debuggers are not an option since I also need to collect this profiling information from website users for monitoring and graphing our web site's page load speeds
Thanks!
There will be no event fired because its virtually impossible for ready() to know when any asynchronous functions are done processing. Thus, you'll need to bake this functionality in yourself; you could use jQuery's custom events, or perhaps set a function to run on setInterval() that can introspect the environment and deduce whether or not everything else is done.
Swap out the jQuery ready function with a function that does your start and finish tracking, and calls the original method.
jQuery.ready = (function() {
var original = jQuery.ready;
return function() {
alert('starting profiler');
original();
alert('ending profiler');
};
})();
$(function() {
alert('this message will appear between the profiler messages above...');
});
Have you tried using Profiler in Firebug?

Categories