AddListener

Share your advanced knowledge/code with the community.
BarJo
Posts: 5
Joined: Mon Dec 18, 2023 9:55 am

AddListener

Post by BarJo »

Hi everyone,

I've been working a bit on a background application issue, made some progress, but it's not sufficient yet. I think I won't be able to complete my test entirely with SpiderBasic; it seems that the Android APIs are not accessible once the app is in the background. In my test, I attempted to retrieve geolocation in the background. It works for the first 5 seconds, and then nothing. I don't have a deep understanding of the Android world, but perhaps there's a missing permission for it to work.

I've created two functions that I don't use but might be useful to you. They may not be perfect, so you can judge.

The first one is AddWorker:
It can replace AddTimer without being tied to a window.

Code: Select all

; Variable pour le test
Global count = 0

; fonction Addlistener
; permet l'execution d'une procedure sans fenetre et fonctionne en arriere plan
; limite:
; ne permet pas l'usage de la geolocalisation en arriere plan par exemple
Procedure AddListener(Timeout.i, *function, argument.s = "")
  Debug "AddListener"
  Define str.s = Str(*function)
  Define func.s, arg.s
  
  !const regex = /^function\s{0,}([f][_][a-z0-9]{1,})\s{0,}\(([a-zA-Z0-9_,\s]{0,})\)/gm;
  !let m;
  !while ((m = regex.exec(v_str)) !== null) {
  !  if (m.index === regex.lastIndex) {
  !    regex.lastIndex++;
  !  }
  !  v_func = m[1];
  !  v_arg = m[2];
  !}
  
  Debug "Timeout: " + Timeout
  Debug "function: " + func.s
  Debug "argument: " + argument + " " + arg.s
  
  ;https://briangrinstead.com/blog/load-web-workers-without-a-javascript-file/
  !// makeWorker is a little wrapper for generating web workers from strings
  !function makeWorker(script) {
  !    var URL = window.URL || window.webkitURL;
  !    var Blob = window.Blob;
  !    var Worker = window.Worker;
  !
  !    if (!URL || !Blob || !Worker || !script) {
  !        return null;
  !    }
  !
  !    var blob = new Blob([script]);
  !    var worker = new Worker(URL.createObjectURL(blob));
  !    return worker;
  !}
  !
  !    self.addEventListener('message', function(e) {
  !        postMessage(e.data / 2);
  !    },false);
  !
  !var inlineWorkerText =
  ; Fonction wait
  !"function wait(ms){ var start = new Date().getTime(); var end = start; while(end < start + ms) { end = new Date().getTime(); }};" 
  !+
  ; listener
  !"self.addEventListener('message', function(e) {while (true) { postMessage('loop') ; wait(Number(e.data)); }; } ,false);";
  !var inlineWorker = makeWorker(inlineWorkerText);
  !inlineWorker.onmessage = function(e) { window[v_func](e.data) };
  !
  !inlineWorker.postMessage(v_timeout);
EndProcedure
  
; fonction de test
Procedure Events()
  Debug count 
  count = count +1
EndProcedure

;ajout du listener
AddListener(5000, @Events())

The second one, AddWorker:
Allows you to execute a function in a threaded manner.

Code: Select all

;fonction AddWorker
; name = nom du worker
; function qui sera executé par le worker (les fonctions SpiderBasic ne sont pas utilisable!)
; retourne l'instance du worker
Procedure.i AddWorker(name.s, *function)
  Define worker
  func.s = Str(*function)
  Debug func
  !//As a worker normally take another JavaScript file To execute we convert the function in an URL: http://stackoverflow.com/a/16799132/2576706
;  !function getScriptPath(foo){ return window.URL.createObjectURL(new Blob([foo.toString().match(/^\s*function\s*\(\s*\)\s*\{(([\s\S](?!\}$))*[\s\S])/)[1]],{type:'text/javascript'})); }
  !v_func = window.URL.createObjectURL(new Blob([v_func.toString().match(/^\s*function\s*[a-z_]*\(\s*\)\s*\{(([\s\S](?!\}$))*[\s\S])return\s*[0-9]/)[1]],{type:'text/javascript'}));
  !
  !/*
  ! *	Here are the workers
  ! */
  !//Worker
;  !var worker = new Worker(getScriptPath(v_func));
  !var v_worker = new Worker(v_func);
  !//We add a listener To the worker To get the response And show it in the page
  !v_worker.addEventListener('message', function(e) {
  !    console.log(e.data);
  !}, false);
  ;!console.log(worker)
;  !worker.postMessage(''); 
  ProcedureReturn worker
EndProcedure

;function StartWorker
; worker = intance du worker
; argument = parametres pour le worker
Procedure StartWorker(worker,argument = '')
  !console.log(v_worker)
  !v_worker.postMessage(v_argument); 
EndProcedure

;function TestWorker
; uniquement en javascript, les fonctions SpiderBasic ne peuvent pas etre utilisés
Procedure TestWorker()
  !self.postMessage('le test: TestWorker');
EndProcedure

;creation de l'instance
test = AddWorker("test", @TestWorker())
;demarrage de l'instance
StartWorker(test)
If you have any ideas or solutions for using geolocation in the background, for example, I'm open to suggestions. But I believe it can only be functional if SpiderBasic allows it.
Dirk Geppert
Posts: 281
Joined: Fri Sep 22, 2017 7:02 am

Re: AddListener

Post by Dirk Geppert »

I'm not sure, but I remember that playing sound keeps the app active.
BarJo
Posts: 5
Joined: Mon Dec 18, 2023 9:55 am

Re: AddListener

Post by BarJo »

Dirk Geppert wrote: Wed Jan 17, 2024 6:53 am I'm not sure, but I remember that playing sound keeps the app active.
Hello,

I don't know, but that would be quite strange.
So, in theory, it would be necessary to broadcast white noise to remain active.
Wouldn't this potentially pose a problem for other apps using sound?
Needs testing.
Thank you.
Post Reply