Yes, I didnt find any case like mine
I try to make a http request inside a Worker in my Nativescript application (with angular), and this cause an app crash
Android
When I try to make a http request inside the worker, by using :
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");
.........
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");
}
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.