NativeScript / android

NativeScript for Android using v8
https://docs.nativescript.org/guide/android-marshalling
Apache License 2.0
525 stars 135 forks source link

Any processMessages type functionality #324

Closed N3ll closed 8 years ago

N3ll commented 8 years ago

From @NathanaelA on January 1, 2016 2:45

Ok, so I'm starting up my application and I'm doing a lots of file, database and raw data processing on startup and once it is all done I switch to the main screen from the startup progress screen. However, even though I am updating the status label and progress bar; you do NOT see any of the changes because of course the main thread has been so busy doing all its work that it never actually had a chance to pass control back down to the android layer apparently to update the screen. (I haven't tried this on iOS yet) Since we don't have background thread ability yet; Is their any way I can force the android runtime to run and update the screen or do I have to split everything up into really small functions that I can then use setTimeout's so that their is a break between each one?

Copied from original issue: NativeScript/NativeScript#1315

N3ll commented 8 years ago

From @x4080 on January 1, 2016 3:35

What if the background process using native android library?

N3ll commented 8 years ago

From @NathanaelA on January 1, 2016 4:26

Actually, I might have to go that way in the future since it is so intensive. But for the prototype I'd rather not write Java and ObjectiveC code if I don't have too. :-)

So in the meantime, in all my exploring I haven't seen anything like this; but there might be a feature somewhere deep in the Runtimes that will allow me to push out of the JS VM back into the Android NDK/Java level and get the screen updated...

N3ll commented 8 years ago

From @x4080 on January 1, 2016 9:25

Yea actually i suggested that sonehow there is 2nd javascript in the background it will be very helpful

N3ll commented 8 years ago

From @NathanaelA on January 2, 2016 17:21

I'm pretty sure a feature to force the runtimes to update the screen (or actually suspend the JS runtimes and make the Android/iOS handle their message loops) is something that doesn't exist; but I figured it couldn't hurt to ask.

@x4080 Having a background thread (which also would solve this, is bug report #85 ); as you can see many people have commented on it. I'm hoping that more people will +1 it so that it will become the top issue. :grinning:

N3ll commented 8 years ago

From @x4080 on January 3, 2016 11:47

Actually i wrote the last comment there :)

NathanaelA commented 8 years ago

Just for anyone following in my footsteps; at least on Android I have to do this:

var page;
exports.navigatedTo = function(args) {
   page = args.object;
   setTimeout(startProcessing, 0);
};

function startProcessing() {
  // get progressbar & label objects
  // Do major processing
  process.processMessages();
 // Do major processing.
  process.processMessages();
 // ...
}

The initial setTimeout is required; because apparently the screen/activity hasn't fully been displayed or and/or the activity messageloop hasn't been primed or something -- Not sure what it is. If I just call the startProcessing() without tossing it off in a setTimeout; the screen just shows blank white the entire time...

The process.processMessages() is the function I modified from @atanasovg suggestions and it will show up in my opensource nativescript-master-technology plugin when I have a chance to release it.

And yes it is a very hacky way of doing it; but based on everything I've researched and messing with several variations of the code; I think it is the only way to do it from JS currently.

The better solution for this feature would be to add a synchronous processMessages function to the runtime that would leave the vm; post a NS_RESUME_VM message to the end of the messageloop. And then drop into the message loop to allow all the message loop messages to be handled; once that message is received it jumps back into the vm as if returning from the processMessages function. Sounds simple enough, but I haven't played with either runtimes message loop code so I couldn't really say.

NathanaelA commented 8 years ago

I used this for a while; but I didn't really like the hackiness of it; and came up with an alternative solution for my case. All my "busy" code is now in promises. When a promise is resolved in that then() I call a function that does the screen updates which itself returns a promise;

so I can do:

DoBusyWork.then(updateScreen('Now Working'))
.then(DoMoreBusyWork)
.then(updateScreen('More work accomplished'))
.then(DoEvenMoreBusyWork)
.then(updateScreen('Wow More done...').
.then(done)

@N3ll this can probably be closed now.