Nativescript: Workers : app crash when making http request

Created on 5 Jan 2017  路  5Comments  路  Source: NativeScript/NativeScript

Did you verify this is a real problem by searching [Stack Overflow]

Yes, I didnt find any case like mine

Tell us about the problem

I try to make a http request inside a Worker in my Nativescript application (with angular), and this cause an app crash

Which platform(s) does your issue occur on?

Android

Please provide the following version numbers that your issue occurs with:

  • CLI: 2.4.2
  • Cross-platform modules: 2.4.4
  • Runtime: tns-android": "version 2.4.1"
  • Plugin(s):
    "nativescript-angular": "1.1.3",
    "nativescript-background-http": "^2.4.0",
    "nativescript-camera": "0.0.8",
    "nativescript-geolocation": "0.0.17",
    "nativescript-loading-indicator": "^2.2.1",
    "nativescript-plugin-firebase": "^3.8.5",
    "nativescript-telerik-ui": "^1.5.1",
    "nativescript-telerik-ui-pro": "file:.....",
    "nativescript-theme-core": "^0.2.1",
    "nativescript-webworkers": "^1.0.4",

Please tell us how to recreate the issue in as much detail as possible.

When I try to make a http request inside the worker, by using :

  • XMLHttpRequest object
  • or Http Nativescript module
  • or Fetch Nativescript module

The application crash with the following error :

An uncaught Exception occurred on "main" thread.
com.tns.NativeScriptException: Cannot find object id for instance=com.tns.gen.org.nativescript.widgets.Async_CompleteCallback@a3a4f72
    at com.tns.Runtime.callJSMethodImpl(Runtime.java:901)
    at com.tns.Runtime.callJSMethod(Runtime.java:895)
    at com.tns.Runtime.callJSMethod(Runtime.java:879)
    at com.tns.Runtime.callJSMethod(Runtime.java:871)
    at com.tns.gen.org.nativescript.widgets.Async_CompleteCallback.onComplete(org.nativescript.widgets.Async$CompleteCallback.java)
    at org.nativescript.widgets.Async$Http$HttpRequestTask.onPostExecute(Async.java:465)
    at org.nativescript.widgets.Async$Http$HttpRequestTask.onPostExecute(Async.java:379)
    at android.os.AsyncTask.finish(AsyncTask.java:660)
    at android.os.AsyncTask.-wrap1(AsyncTask.java)
    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:677)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6077)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

For informations, all others operations works perfectly in the worker, like using AppSettings module, etc..
Also, when I try my code inside a web application (with angular2) it's works for making http request

I've also tried inside the project https://github.com/NativeScript/demo-workers, and I get the same error crash by adding this code in app\workers\grayscaler.js :

onmessage = function (msg) {

    var req = new XMLHttpRequest();
    req.open('POST', 'http://requestb.in/1gn63fo1', false); 
    req.send("toto=tata");
        .........

Is there code involved? If so, please share the minimal amount of code needed to recreate the problem.

app.component.ts :

var myWorker = new Worker('./app.worker');

// Define response from webworker
myWorker.onmessage = (m) => { console.log("Webworker said:", JSON.stringify(m)); };
myWorker.onerror = (e) => {
     console.log("Error thrown and not caught in worker thread: " + e);
}
myWorker.postMessage("Hello");

app.worker.js :

require('globals');

onmessage = function (msg) {
    var req = new XMLHttpRequest();
    req.open('POST', 'http://requestb.in/1gn63fo1', false); 
    req.send("toto=tata");
}
bug done android

All 5 comments

Hey @GrEg00z, while I haven't debugged the project, I'd like to point out that the http and fetch modules are implemented using AsyncTask (they work on a background thread) and it shouldn't be necessary to offload methods of those particular modules to a worker thread.

Thanks @Pip3r4o,

I know that it's not necessary to create a worker to use http module as "background task", I already using it inside my services application, and in fact it's work asynchroniously.

But my requirement is to use http module in a worker because I need to delegate some background task, like make a synchronisation between my local data and a remote API, to keep an offline mode.
And I dont want to perform this task in the main thread, to save maximum performance and less code complexity.

But the subject here is there is a real bug in nativescript workers, because they are also maked to perform http request, and not only for image traitement.

Note :
I have also take a look on everlive plugin, and specially on Offline Capability (here), but it doesnt match with my project because the remote API interacts with a mongoDB server, no SQL server.

@GrEg00z I debugged the project and found that there is indeed a bug, or rather - a limitation, that currently causes the http module to be unable to return a result. I think this has to do more with how http is currently implemented (AsyncTask).
An implementation of the org.nativescript.widgets.Async$CompleteCallback interface is created on the worker thread in JavaScript, but the AsyncTask tries to call it on the main thread - hence the .. Exception occurred on 'main' thread:.. (which is obviously wrong, but AsyncTask returns results to the main), and the two threads share no common memory.

According to the official Android docs:

There are a few threading rules that must be followed for this class to work properly:

  • The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
  • The task instance must be created on the UI thread.
  • execute(Params...) must be invoked on the UI thread.

Having said that - I cannot think of an easy and quick solution at the moment, you can however delegate http requests to main, and post results to workers whenever you need to use http/fetch

Hey @GrEg00z,

We will do our best to address this ASAP and in the meantime you can use this plugin instead:
https://www.npmjs.com/package/nativescript-https

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yclau picture yclau  路  3Comments

OscarLopezArnaiz picture OscarLopezArnaiz  路  3Comments

rogangriffin picture rogangriffin  路  3Comments

rLoka picture rLoka  路  3Comments

dhanalakshmitawwa picture dhanalakshmitawwa  路  3Comments