Adobe air runtime evita que se inicie al mismo tiempo más de una instancia de una aplicación de aire. ¿Es seguro eludir esta restricción cambiando arbitrariamente la ID del editor? ¿Alguien sabe si Adobe planea permitir múltiples instancias concurrentes en Air 2.0?iniciar una aplicación de Adobe AIR varias veces
Respuesta
Implementamos con éxito un truco para eludir esta limitación, de forma puramente AIR, sin tener que cambiar la id del editor (que necesita varios certificados, creo).
Como ya sabe, AIR implementa su Mutex utilizando un identificador de aplicación único. Este identificador se calcula utilizando el ID de la aplicación y el identificador del editor (extraído del certificado que firmó la aplicación).
En el directorio de instalación de una aplicación de AIR, hay una carpeta META-INF (o en/share/using Linux). Esta carpeta META-INF contiene una carpeta AIR, que contiene un archivo "application.xml". Este archivo contiene una etiqueta <id />
que define el identificador de la aplicación, que se utiliza en el cálculo del identificador mutex. Si su aplicación puede escribir en la carpeta de instalación, puede usar la API File
para editarla en tiempo de ejecución, cambiando aleatoriamente la etiqueta <id />
, permitiendo que varios procesos de la misma aplicación se ejecuten al mismo tiempo.
Esto está teniendo algunos efectos secundarios molestos, como crear una nueva carpeta en la carpeta File.applicationStorageDirectory
todo el tiempo. Pero utilizando un LocalConnection
, puede minimizar esto reutilizando el mismo identificador varias veces al iniciar sesión, cuáles son libres de reutilización. Además, SharedObject
se almacenan en esta carpeta, por lo que no se pueden usar (o tienen que copiarse cada vez que se crea una nueva instancia, y se sincronizan a través de LocalConnection
).
Por lo que sé, Adobe no planea eliminar esta limitación nativa. Se implementó para propósitos de plataformas múltiples, específicamente en MacOS, donde el dock lo hace más complicado (no es muy fácil comenzar la misma aplicación dos veces con el dock).
La forma oficial de hacerlo es detectar el evento InvokeEvent.INVOKE
y hacer cosas como abrir una nueva ventana. Y no hay cambios planeados para AIR 2.0 en este comportamiento.
¿Te ayudaría si encapsulas la lógica de tu aplicación como una clase que podría ejecutarse en una ventana y permitir al usuario crear varias instancias de esa ventana, dentro de una aplicación? ¿Eso ayudaría?
¿Cuál es la razón principal por la que necesitaría múltiples aplicaciones?
Gracias por la respuesta, pero específicamente estoy buscando procesos separados. Hay una serie de beneficios, por ejemplo, ejecución paralela en computadoras multiprocesador. – abc
Ya veo, gracias por la explicación. Buena pregunta. Puede tener procesos separados en Java ... esto podría ser demasiado largo, sería bueno hacer interfaz entre AIR y Java a través de Merapi (http://merapiproject.net/). –
Nuevamente, publicación interesante, pero está fuera de tema. Merapi es un marco de IPC en lugar de un marco de enlace (como JNI), por lo que no es posible vincularlo a una biblioteca de Java multiproceso; tendría que haber un proceso Java por separado. Además, usar un java helper solo proporcionaría procesamiento paralelo, no otras ventajas de procesos múltiples. Volvamos a la pregunta original: estoy buscando una manera de iniciar varias instancias de una aplicación Flex AIR, y específicamente si es legal ejecutar el mismo swf con múltiples identificadores de editores en el tiempo de ejecución de AIR. – abc
Esto romperá la actualización automática, tenga cuidado.
Air Application duplicator le ayudará en esta parte. Al usar esto, puede ejecutar múltiples instancias de la misma aplicación de AIR.
https://github.com/chrisdeely/AirAppDuplicator
Su simplemente copiando el directorio de aplicación con el nuevo nombre y la nueva ID de aplicación.
Acabo de hacer una clase rápida para implementar la solución de Tyn. Simplemente llama. MultipleInstanceAirApp.changeMetaInfId(stage);
Realmente no necesita la parte de escenario, pero la utilizo para cambiar la posición de la ventana cuando la pruebo. De todos modos, ¡disfrútalo!
import flash.display.Stage;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.utils.ByteArray;
/**
* @author Lachhh
*/
public class MultipleInstanceAirApp {
static private var loadFile : File;
static private var thePath:String = "./META-INF/AIR/application.xml";
static private var myGameId:String = "YOUR_GAME_ID";
static private var stage:Stage ;
static private var metaInfString:String ;
static public var instanceNumber:int = 0;
static public function changeMetaInfId(pStage:Stage):void {
stage = pStage;
var path:String = File.applicationDirectory.resolvePath(thePath).nativePath;
loadFile = new File(path);
loadFile.addEventListener(Event.COMPLETE, onLoadMetaInf);
loadFile.addEventListener(IOErrorEvent.IO_ERROR, onIoError);
loadFile.load();
}
private static function onLoadMetaInf(event : Event) : void {
loadFile.removeEventListener(Event.COMPLETE, onLoadMetaInf);
metaInfString = loadFile.data.toString();
replaceMetaInfIdIfFound();
saveStringToMetaInf(metaInfString);
}
static public function saveStringToMetaInf(s:String):void {
var b:ByteArray = new ByteArray();
b.writeUTFBytes(s);
saveFile(b);
}
static public function saveFile(data:ByteArray):void {
var thePath:String = File.applicationDirectory.resolvePath(thePath).nativePath;
var saveFile:File = new File(thePath);
var fileStream:FileStream = new FileStream();
fileStream.openAsync(saveFile, FileMode.WRITE);
fileStream.writeBytes(data);
fileStream.addEventListener(Event.CLOSE, onClose);
fileStream.close();
}
static private function replaceMetaInfIdIfFound():void {
if(checkToReplaceId(1, 2)) return ;
if(checkToReplaceId(2, 3)) return ;
if(checkToReplaceId(3, 4)) return ;
checkToReplaceId(4, 1);
}
static private function checkToReplaceId(i:int, newI:int):Boolean {
var id:String = getGameIdWithBrackets(i);
var newId:String = getGameIdWithBrackets(newI);
if(metaInfString.indexOf(id) != -1) {
metaInfString = myReplace(metaInfString, id, newId);
instanceNumber = newI;
return true;
}
return false;
}
private static function onClose(event : Event) : void {
trace("all done!");
placeScreenAccordingToInstanceNumber();
}
static private function placeScreenAccordingToInstanceNumber():void {;
switch(instanceNumber) {
case 1 :
stage.nativeWindow.x = 115;
stage.nativeWindow.y = 37;
break;
case 2 :
stage.nativeWindow.x = 115 + 660;
stage.nativeWindow.y = 37;
break;
case 3 :
stage.nativeWindow.x = 115;
stage.nativeWindow.y = 37 + 380;
break;
case 4 :
stage.nativeWindow.x = 115 + 660;
stage.nativeWindow.y = 37 + 380;
break;
}
}
private static function onIoError(event : IOErrorEvent) : void {
trace("io Error");
}
static private function getGameIdOriginalWithBrackets():String {
return "<id>" + myGameId + "</id>";
}
static private function getGameIdWithBrackets(i:int):String {
if(i == 1) return getGameIdOriginalWithBrackets();
return "<id>" + myGameId + i + "</id>";
}
static public function myReplace(msg:String, toFind:String, toBeReplacedWith:String):String {
return msg.split(toFind).join(toBeReplacedWith) ;
}
}
package hobis.airpc
{
import flash.events.Event;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.utils.ByteArray;
import jhb0b.utils.MArrayUtil;
public final class MAppXmlUpdateCounter
{
private static var _AppXmlFile:File;
public static function Update():void
{
_AppXmlFile = new File(File.applicationDirectory.nativePath);
_AppXmlFile = _AppXmlFile.resolvePath('META-INF\\AIR\\application.xml');
_AppXmlFile.addEventListener(Event.COMPLETE, ppOpened);
_AppXmlFile.load();
}
private static function ppOpened(evt:Event):void
{
const trx1:RegExp = /<id>[\s\S]*?<\/id>/;
const trx2:RegExp = /<([^>]+)>/g;
var tXmlStr:String = _AppXmlFile.data.toString();
var tMatArr:Array = tXmlStr.match(trx1);
if (!MArrayUtil.is_empty(tMatArr))
{
var tIdTagStr:String = tMatArr[0];
var tIdValStr:String = tIdTagStr.replace(trx2, '');
var tOriVal:String;
var tNumVal:uint;
var tStrArr:Array = tIdValStr.split('-');
if (tStrArr != null)
{
if (tStrArr.length == 2)
{
tOriVal = tStrArr[0];
tNumVal = int(tStrArr[1]);
}
else
if (tStrArr.length == 1)
{
tOriVal = tStrArr[0];
tNumVal = 0;
}
tNumVal++;
var tIdNewStr:String = '<id>' + tOriVal + '-' + tNumVal + '<\/id>';
var tNewXmlStr:String = tXmlStr.replace(tIdTagStr, tIdNewStr);
ppSaveFile(tNewXmlStr);
}
}
_AppXmlFile = null;
}
private static function ppSaveFile(val:String):void
{
var tfs:FileStream;
try
{
tfs = new FileStream();
tfs.openAsync(_AppXmlFile, FileMode.WRITE);
var tba:ByteArray = new ByteArray();
tba.writeUTFBytes(val);
tfs.writeBytes(tba);
tba.clear();
}
catch (e:Error) { }
try
{
tfs.close();
}
catch (e:Error) { }
}
}
}
¡Bienvenido a Stack Overflow! Aunque este fragmento de código es bienvenido, y puede brindar cierta ayuda, sería [mejorado mucho si incluyera una explicación] (// meta.stackexchange.com/q/114762) de * cómo * aborda la pregunta. Sin eso, tu respuesta tiene mucho menos valor educativo: recuerda que estás respondiendo la pregunta a los lectores en el futuro, ¡no solo a la persona que pregunta ahora! Por favor [edite] su respuesta para agregar una explicación y dar una indicación de qué limitaciones y suposiciones se aplican. –
- 1. Adobe air varias aplicaciones en un instalador
- 2. Adobe Air: Iniciar ventana nativa oculta
- 3. Adobe AIR 512x512 Iconos?
- 4. protección de adobe air apps
- 5. Cómo establecer el icono en una aplicación de adobe air
- 6. ¿Qué es Adobe Air?
- 7. Silverlight vs Adobe Air
- 8. Adobe Air y .NET
- 9. ¿Es posible ejecutar una aplicación Adobe AIR sin instalación?
- 10. Cómo reiniciar una aplicación independiente Adobe Air/Flex
- 11. Adobe AIR para ejecutar el programa
- 12. ¿Qué sentido tiene Adobe AIR?
- 13. LoaderContext y ApplicationDomain cambia con Adobe AIR?
- 14. Acceso al puerto serie en Adobe-Air
- 15. Descargar un archivo con Adobe AIR
- 16. Creación de una arquitectura de complemento con Adobe AIR
- 17. ¿Herramientas de desarrollo para Adobe Flex/AIR?
- 18. Descompilación de aplicaciones de Adobe AIR
- 19. Pasar parámetros de una actividad java a la aplicación Adobe AIR
- 20. cómo instalar adobe air sdk en Linux?
- 21. as3 | Cómo exportar PNG usando Adobe AIR
- 22. Diferencia entre Adobe AIR y FLEX?
- 23. ¿Puedo asignar una tecla rápida global a una aplicación Adobe AIR?
- 24. Adobe Air vs Flash Player 10.1 Tiempo de ejecución
- 25. ¿Cómo puedo crear un proyecto de Adobe Air con Maven?
- 26. Impresión en Adobe AIR - Generación de PDF independiente
- 27. Adobe AIR y diferentes sistemas de archivos del sistema operativo
- 28. Detección mediante programación entre Adobe Air y Adobe Flex en ActionScript 3.0
- 29. ¿Cómo puedo iniciar varias instancias de una aplicación usando launchd?
- 30. Instalación de archivo de Adobe Air falla con "archivo dañado"
buenas respuestas por favor para ganar la recompensa. – abc