|
||
|
![]() |
![]() |
Tasker Para hablar de todo lo relacionado con la aplicación tasker |
![]() |
|
Herramientas |
#1
|
||||
|
||||
[HILO ESPECÍFICO] Integración de JavaScript en Tasker
INTRODUCCIÓN Y JUSTIFICACIÓN
Sin ánimo de complicar mucho el porqué de la conveniencia ó necesidad de integrar código de JavaScript en nuestros programas de Tasker hay que recordar que el entorno de programación que usamos está por encima de los lenguajes llamados de Alto nivel (Java, JavaScript, Perl, PHP, Python,...). El entorno Tasker nos libera de escribir instrucciones, cada una con su sintaxis propia, puntuación, paréntesis, llaves, corchetes, ... y nos presenta unas "fichas" (los perfiles, las tareas, las escenas) con acciones concretas en las que ponemos los parámetros y variables que intervienen. Tasker, en la ejecución, convierte estas acciones en instrucciones de un lenguaje de alto nivel que, a su vez, traduce a código inteligible por la máquina. Esta doble traducción sitúa Tasker como un lenguaje de "altísimo nivel". Esto no quiere decir que sea el no va más (aunque nos funciona muy bién). Al contrario, esta doble traducción ralentiza sensiblemente, en segun que acciones, la ejecución del programa. Desde mi humilde punto de vista és un lenguaje para "bricolage": tiene sus limitaciones pero es muy amigable de usar. Entre estas limitaciones: no se puede hacer "scroll" vertical u horizontal entre escenas (al menos yo no sé como hacerlo), es complicado diseñar las escenas para que se adapten a distintas resoluciones/tamaño de pantalla, etc., hay una que, a mí, me resulta especialmente inconveniente: Los programas que hago acostumbran a usar bases de datos para procesar, ordenar, consultar, extraer los campos que contienen y mostrar los resultados en escenas. Este proceso se basa casi siempre en iteraciones (repeticiones) programadas con acciones dentro de un bucle "For" - "EndFor" con sus correspondientes "Si" - "Fin si" dentro... La doble conversión de instrucciones (Tasker > Lenguaje de alto nivel > Lenguage más cercano a la máquina) hace muy lenta la ejecución en cuanto los datos a procesar sean un poco cuantiosos. Una posible solución es convertir el Proyecto a aplicación con el Factory. El problema entonces es que cada modificación que hagamos en el código inicial (mejora, ampliación, revisión, etc.) acaba convertida en una APK nueva. Como el Factory las numera automáticamente, yo he llegado a tener casi 100 versiones de una misma APK...! La otra solución (que és la buena) consiste en saltarse, para determinadas acciones, esta "capa intermedia" que es Tasker y escribirlas directamente en un lenguaje de Alto nivel. De este modo, en la ejecución desde el entorno Tasker, nos ahorramos la interpretación de estas acciones mas "pesadas". Afortunadamente Tasker tiene previsto estos "atajos". En el grupo de acciones CÓDIGO tenemos: Ejecutar cónsola, Ejecutar script, Java Function, Java Object, JavaScript y JavaScriptlet. Estas acciones nos ofrecen la posibilidad de "bajar de nivel" y mejorar nuestros programas. Otra ventaja indudable que nos ofrece el uso de este tipo de acciones es que en el entorno Tasker aparecen como una sola acción, aunque "dentro" incluyan un buen número de instrucciones de JS. Esto facilita mucho la revisión de nuestro código. Este hilo pretende agrupar las discusiones, preguntas, propuestas y soluciones que los compañeros puedan aportar relativas al uso de JS en Tasker RECOPILATORIO DE APORTACIONES --> Nada mejor para empezar que un enlace a un magistral post de @maid450 en el foro que, hace pocos dias, me abrió el cielo: [Tutorial] Creación, uso y manipulación de variables con javascript --> Enlace a un post mio en el que se debatia la conveniencia de abrir un hilo específico para JS y en donde pongo un sencillo ejemplo de comparación del tiempo de ejecución entre Tasker y JS. http://www.htcmania.com/showpost.php...&postcount=273 --> Calcular la distancia entre dos puntos dados por coordenadas GPS (@WillyWeb) http://www.htcmania.com/showthread.php?t=1026246 --> Formatear un entero con separación de millares (@maid450) http://www.htcmania.com/showpost.php...2&postcount=38 --> Como lanzar una app de manera dinámica (con variable) y como obtener el nombre de las apps (@mlesir) http://www.htcmania.com/showthread.php?t=1159277 Una muestra más de la simplicidad con que se pueden resolver algunas cosas que en Tasker resultan muy elaboradas (versión @Caravantes) con JS (versión @danko9696) --> Subtarea que devuelve la fecha en formato AAAA-MM-DD (Caravantes, danko9696, maid450...) http://www.htcmania.com/showthread.php?t=1160655 --> Expresión regular para búsqueda dentro de una variable (@maid450) http://www.htcmania.com/showthread.php?t=1161396 --> Cálculo de la letra del DNI http://www.htcmania.com/showpost.php...3&postcount=26 --> Código en JS para Lightning Launcher que sirve para enviar a Tasker la página actual del escritorio http://www.htcmania.com/showpost.php...5&postcount=27 --> Extracción de datos de un archivo JSON (resultado de bajar datos de una API) con Javascript -a partir del post #45- http://www.htcmania.com/showthread.php?t=1289407&page=3
__________________
Me apasiona volar, pero con los pies en el suelo...
Última edición por cace0353 Día 28/02/17 a las 19:02:24. |
Los siguientes 2 usuarios han agradecido a cace0353 su comentario: | ||
|
#2
|
||||
|
||||
Reservado
__________________
Me apasiona volar, pero con los pies en el suelo...
|
Gracias de parte de: | ||
#3
|
||||
|
||||
En mi primera aportación a este hilo (y espero que no sea la última) pongo el enlace a un tema en el que he usado JavaScript para solventar una par de carencias de Tasker en lo tocante al manejo de decimales y funciones trigonométricas.
Calcular la distancia entre dos coordenadas http://www.htcmania.com/showthread.php?t=1026246
__________________
Miembro del equipo que promueve el [Subforo de Tasker]
Si das pescado a un hombre hambriento le nutres una jornada. Si le enseñas a pescar le nutrirás toda la vida. (Lao-Tsé - Filósofo chino) |
Los siguientes 2 usuarios han agradecido a WillyWeb su comentario: | ||
#4
|
||||
|
||||
__________________
Me apasiona volar, pero con los pies en el suelo...
|
Gracias de parte de: | ||
#5
|
||||
|
||||
Bueno pues una humilde aportación a este hilo:
"Como lanzar una app de manera dinámica (con variable) y como obtener el nombre de las apps". Autolaunch quizas ya no lo necesitarás: http://www.htcmania.com/showthread.php?t=1159277 Enviado desde mi T1-701u mediante Tapatalk
__________________
Fdo: Mlesir. Miembro del equipo que promueve el foro y el recopilatorio de Tasker http://www.htcmania.com/forumdisplay.php?f=969
|
Los siguientes 4 usuarios han agradecido a mlesir su comentario: | ||
#6
|
||||
|
||||
Buenas, estoy empezando a implementar JS en algunas tareas en las que necesitó mejorar la velocidad de ejecución, y quería compartir una que aunque es aparentemente simple, he notado una mejora considerable.
Para que os hagáis una idea, tengo una escena con cuatro elementos vinculados entre si, que resalto añadiéndole un borde, según pulse cada uno de ellos. Para conseguir esto antes utilizaba siete acciones, y ahora me lo cargo de un plumazo con este código. setGlobal("WH_IconoBT",1- global("WH_IconoBT")); setGlobal ("WH_leer",2); if (global("WH_IconoBT")==1) { var ok = elemBorder( "WH_2 Desplegable", "Icono Bluetooth", 9, "#FFFFFFFF"); var ok = elemBorder( "WH_2 Desplegable", "Icono Sonido", 0, "#FFFFFFFF"); var ok = elemBorder( "WH_2 Desplegable", "Icono Silencio", 0, "#FFFFFFFF"); } else { var ok = elemBorder( "WH_2 Desplegable", "Icono Bluetooth", 0, "#FFFFFFFF"); }; if (global("WH_IconoWifi")<1&& global("WH_IconoBT")<1) { var ok = elemBorder( "WH_2 Desplegable", "Icono Silencio", 9, "#FFFFFFFF"); }; Posiblemente se pueda depurar un poco, pero bueno prácticamente llevo tres días intentando aprender JS. Un saludo. |
Los siguientes 3 usuarios han agradecido a Rsc su comentario: | ||
#7
|
||||
|
||||
¿Y dices que has notado que mejora la velocidad de ejecución de la escena?
¿Dónde has puesto ese código? ... ¿directamente en las acciones del CLIC de un objeto?
__________________
Miembro del equipo que promueve el [Subforo de Tasker]
Si das pescado a un hombre hambriento le nutres una jornada. Si le enseñas a pescar le nutrirás toda la vida. (Lao-Tsé - Filósofo chino) |
#8
|
||||
|
||||
-duplicado-
__________________
Miembro del equipo que promueve el [Subforo de Tasker]
Si das pescado a un hombre hambriento le nutres una jornada. Si le enseñas a pescar le nutrirás toda la vida. (Lao-Tsé - Filósofo chino) |
#9
|
||||
|
||||
No entiendo muy bién (no sé los nombres de las variables que usas) pero me parece que lo que ha conseguido el compañero @Rsc és reducir el listado de acciones en su tarea (o en el grupo de acciones asociadas al "clic").
Donde de verdad se nota el aumento de velocidad es en las operaciones sobre un número elevado de elementos, p.e. en los bucles For...End for, o sobre las variables de las matrices de datos. Enviat des del meu Nexus 5 usant Tapatalk
__________________
Me apasiona volar, pero con los pies en el suelo...
|
Gracias de parte de: | ||
#10
|
||||
|
||||
![]()
__________________
Miembro del equipo que promueve el [Subforo de Tasker]
Si das pescado a un hombre hambriento le nutres una jornada. Si le enseñas a pescar le nutrirás toda la vida. (Lao-Tsé - Filósofo chino) |
#11
|
||||
|
||||
Otra ventaja muy importante es que se maneja muchísimo más comodamente que las acciones de Tasker cuando se trata de tareas largas/complejas por poder escribir y visualizar el código en PC, de modo que se puede ver más código a la vez y moverse entre él de forma más ágil, comentar extensivamente sin problema (en Tasker también se puede pero hay que ser más selectivo dado el reducido espacio de pantalla), usar ratón y teclado, copypaste más cómodo y luego copiar el texto al móvil .
El inconveniente que veo es que no se puede hacer ejecución paso a paso, que algunos errores no son mostrados como tales y que obviamente hay que tener más cuidado con la sintaxis. Pero en tareas complejas, incluso aunque el rendimiento fuese algo peor (en lugar de bastante mejor) merecería la pena, simplemente porque desarrollarlas sería una pesadilla con acciones de Tasker. Creo que lo único que no se puede es controlar plugins (confirmado en una duda con el desarrolador), pero salvo eso creo que practicamente todo lo demás. |
Gracias de parte de: | ||
#12
|
||||
|
||||
Tengo cuatro iconos en una escena. - Sonido activado. - Sonido desactivado - Sonido solo con Bluetooth conectado. - Sonido solo con WiFi conectado Lo que hago es añadir o eliminar bordes a los elementos al pulsar sobre uno de ellos, para que la escena muestre que modo de sonido tengo activado en ese momento. Quizás también tenía que haber concertado mejor lo de "mejora considerable" , realmente utilizando las siete acciones que tenía antes, haciendo un eso normal de la escena, conseguía hacer lo mismo y no se aprecia ningún retardo desde que hago clic, hasta que se modifican los elementos, por lo menos a simple vista, PERO, si que es cierto que testeando, alternando rápido entre los iconos, si que notaba ese retardo, y frecuentemente no respondía, ya que se estaban ejecutando las acciones. En cambio, con el código de JS puedo alternar entre los iconos todo lo rápido que quiera, y siempre responde perfectamente. También, tengo entendido que al exportarlo como app, se reduce el tiempo de ejecución, y en estas pruebas, las acciones normales las he probando en una escena de una app, y la escena en la que utilizó JS, en un proyecto de Tasker. En este caso solo son cuarto iconos, pero normalmente cuando muestro una escena, la suelo acompañar de muchas acciones relativas a los elementos, y espero notar más aún las mejoras. @cace0353 No entiendo muy bién (no sé los nombres de las variables que usas) No hay quien las entienda, les pongo nombres que hacen daño a la vista, pero es la única manera de mantenerlas agrupadas ![]() Última edición por Rsc Día 14/12/16 a las 01:59:36. |
Los siguientes 2 usuarios han agradecido a Rsc su comentario: | ||
#13
|
||||
|
||||
![]()
__________________
Miembro del equipo que promueve el [Subforo de Tasker]
Si das pescado a un hombre hambriento le nutres una jornada. Si le enseñas a pescar le nutrirás toda la vida. (Lao-Tsé - Filósofo chino) |
#14
|
||||
|
||||
Buenas de nuevo. Para comprobar cuanto tiempo mejoraba exactamente la tarea al ejecutarla con el código de JS, he calculado cuantos milisegundos tardaba en completarse cada una, y me acabo de llevar un chasco tremendo.
La tarea ejecutada con JS, oscila entre los 150 y 200 ms, mientras que la tarea ejecutada con las acciones nativas de Tasker oscila entre 20 y 50 ms. La verdad que no lo entiendo, ayer haciendo las comprobaciones que comenté, notaba que los elementos en los que utilizaba el código de JS respondían mejor y más raido. Si que es cierto que las tareas con las que hice ayer las comprobaciones, aunque realizaba el mismo número de acciones, no eran exactamente las mismas, ya que en las que utilizaba Tasker, modificaba el color de los elementos, y en las que utilizaba JS añadía o eliminaba los bordes de los elementos. En definitiva, comprobado el tiempo de ejecución de la misma tarea exactamente, resulta más efectivo realizarla con las acciones de Tasker, por lo menos en esta tarea concretamente. No obstante seguiré haciendo comprobaciones, con tareas que tengas más acciones, y acciones como las que comenta @cace0353 de bucles For...End etc en las que dice que se nota más la diferencia en utilizar JS. Que por cierto, cuando tengas un hueco podrías poner como utilizar bucles con JS porque no tengo ni idea. Además, copio aquí el código de JS de mi tarea, con un par de modificaciones, por si alguien sabe si se pudiera simplificar/optimizar, porque a mi se me escapa. setGlobal("WH_IconoBT",1- global("WH_IconoBT")); if (global("WH_IconoBT")==1) { setGlobal("WH_leer",2) var ok = elemBorder("WH_2 Desplegable","Icono Bluetooth",9,"#FFFFFFFF") var ok = elemBorder("WH_2 Desplegable","Icono Sonido", 0,"#FFFFFFFF") var ok = elemBorder("WH_2 Desplegable","Icono Silencio",0,"#FFFFFFFF") } else { var ok = elemBorder("WH_2 Desplegable","Icono Bluetooth",0,"#FFFFFFFF") } if (global("WH_IconoWifi")<1&& global("WH_IconoBT")<1) { setGlobal("WH_leer",0) var ok = elemBorder("WH_2 Desplegable","Icono Silencio",9,"#FFFFFFFF") } Un saludo. Última edición por Rsc Día 14/12/16 a las 13:06:39. |
#15
|
||||
|
||||
Esa diferencia, teniendo en cuenta que se trata de unas pocas lineas secuenciales, está muy bien. Es como pasar de jugar (hace años) de linea telefónica a hacerlo en red local.
Pero como te han dicho antes es en bucles y manejo de cadenas donde la diferencia se vuelve enorme. Yo he observado mejoras de hasta cien veces más rápido en tareas bastante complejas con bucles y arrays de cadenas anidados, de 160 segundos a alrededor de uno, y este uno con más cosas añadidas. Y como puse antes, con la ventaja de que resulta mucho más sencillo manejar el código y hacer cambios cuando lo puedes ver en un archivo de texto en el PC. Aquí tienes más ejemplos, pero te pueden servir guías o tutoriales en internet sobre javascript en general, no tiene por qué estar limitado a Tasker. Y lo que aprendas también lo puedes usar luego en Lightning Launcher, que es el launcher con mayor integración con Tasker. http://www.htcmania.com/showthread.php?p=9170995 |
#16
|
||||
|
||||
Y gracias, le iré echando un vistazo a JS, pensaba que había más diferencias al implementarlo en Tasker |
#17
|
||||
|
||||
Pués sí, lo entendí al revés. Unas preguntas: ¿como has comprobado el tiempo en JS/Tasker, usando TIMEMS? ¿has repetido las pruebas en diferente orden de ejecución (primero tasker luego JS y viceversa)? ¿Sigues notando mejor respuesta en JS con las mismas acciones exactamente aunque te de peor tiempo?
Una sugerencia para optimizar puede ser que a la hora de leer las variables con global, si lo vas a hacer más de una vez es mejor asignarlas a una variable local y utilizar esta, para luego al final hacer un setGlobal si es necesario. Por ejemplo, veo que usas varias veces global("WH_IconoBT") cuando esto solo debería ocurrir una vez. Es parecido al uso de variables globales en tareas de Tasker. Salvo que se vayan a usar una sola vez mejor asignarlas a variables locales para operar con ellas. var v_IconoBT = 1-global("WH_IconoBT"); var v_IconoWifi = global("WH_IconoWifi"); setGlobal("WH_IconoBT",v_IconoBT); if (v_IconoBT==1) { setGlobal("WH_leer",2); elemBorder("WH_2 Desplegable","Icono Bluetooth",9,"#FFFFFFFF"); elemBorder("WH_2 Desplegable","Icono Sonido", 0,"#FFFFFFFF"); elemBorder("WH_2 Desplegable","Icono Silencio",0,"#FFFFFFFF"); } else { elemBorder("WH_2 Desplegable","Icono Bluetooth",0,"#FFFFFFFF"); } if (v_IconoWifi<1 && v_IconoBT<1) { setGlobal("WH_leer",0); elemBorder("WH_2 Desplegable","Icono Silencio",9,"#FFFFFFFF"); } Por cierto, ¿estás seguro de que se ha ejecutado bien?, porque veo que faltaba algún punto y coma. |
#18
|
||||
|
||||
Hola RSC,
No obstante seguiré haciendo comprobaciones, con tareas que tengas más acciones, y acciones como las que comenta @cace0353 de bucles For...End etc en las que dice que se nota más la diferencia en utilizar JS. Que por cierto, cuando tengas un hueco podrías poner como utilizar bucles con JS porque no tengo ni idea.
![]() http://www.htcmania.com/showpost.php...&postcount=273 en el que hay un ejemplo de un bucle para buscar los registros que cumplen dos condiciones simultáneamente (filtros) con una acción de JS. La ganancia en velocidad era apreciable. Pero, a medida que aumentaba el número de registros, la cosa seguia pareciéndome lenta. Para manipular bases de datos, he encontrado que es mucho más efectivo usar Sqlite3, aunque esto implica que debes ser SuperUsuario (root). No obstante he leido por ahí que la próxima versión de Tasker incorporará Sqlite de modo nativo. La misma aplicación del post (cuando puse el ejemplo estaba en una fase inicial) usa ahora una base de datos Sqlite con dos tablas: una de casi 3.000 registros y la otra con unos 500. Con Sqlite, con unos pocos comandos de consulta simples, la aplicación es realmente operativa y rápida. Ya casi no uso JS.
__________________
Me apasiona volar, pero con los pies en el suelo...
|
#19
|
||||
|
||||
Hola RSC,
En el primer hilo del post tienes este link: http://www.htcmania.com/showpost.php...&postcount=273 en el que hay un ejemplo de un bucle para buscar los registros que cumplen dos condiciones simultáneamente (filtros) con una acción de JS. La ganancia en velocidad era apreciable. Pero, a medida que aumentaba el número de registros, la cosa seguia pareciéndome lenta. Para manipular bases de datos, he encontrado que es mucho más efectivo usar Sqlite3, aunque esto implica que debes ser SuperUsuario (root). No obstante he leido por ahí que la próxima versión de Tasker incorporará Sqlite de modo nativo. La misma aplicación del post (cuando puse el ejemplo estaba en una fase inicial) usa ahora una base de datos Sqlite con dos tablas: una de casi 3.000 registros y la otra con unos 500. Con Sqlite, con unos pocos comandos de consulta simples, la aplicación es realmente operativa y rápida. Ya casi no uso JS. ![]() |
Los siguientes 2 usuarios han agradecido a danko9696 su comentario: | ||
|
#20
|
||||
|
||||
Pués sí, lo entendí al revés. Unas preguntas: ¿como has comprobado el tiempo en JS/Tasker, usando TIMEMS? ¿has repetido las pruebas en diferente orden de ejecución (primero tasker luego JS y viceversa)? ¿Sigues notando mejor respuesta en JS con las mismas acciones exactamente aunque te de peor tiempo?
![]() Me di cuenta que al parecer en Tasker no era necesario utilizarlos, porque la tarea funciona perfectamente. Así que al final, con la intención de mejorar la velocidad de ejecución, eliminé todos los espacios, puntos y comas y todo lo que dentro de mis pocos conocimientos, pensaba que podía requerir tiempo de lectura. Tenía pensado hacer un pequeño resumen con lo que he conseguido hacer por el momento con esa nueva acción, pero quería tener claro algunos detalles que se me escapan primero. Pero vamos, te puedo adelantar que accedo a la DB de los contactos, sin necesidad de ser root a través de esta acción. Obviamente, a las bases de datos de Whatsapp etc, no se podrá acceder con esta acción sin ser root. |
Gracias de parte de: | ||
![]() |
![]() |
||||||
|