Adobe AIR Runtime impedisce l'avvio simultaneo di più istanze di un'applicazione Air. È sicuro aggirare questa restrizione modificando arbitrariamente l'ID del publisher? Qualcuno sa se Adobe prevede di consentire più istanze concorrenti in Air 2.0?avvio di un'applicazione Adobe AIR più volte
risposta
Abbiamo implementato con successo un hack per aggirare questa limitazione, in puro modo AIR, senza dover modificare l'id del publisher (che necessita di più certificati, penso).
Come sapete, AIR sta implementando il suo Mutex utilizzando un identificatore di applicazione univoco. Questo identificatore viene calcolato utilizzando l'ID applicazione e l'identificatore del publisher (estratto dal certificato che ha firmato l'applicazione).
Nella directory di installazione di un'applicazione AIR, esiste una cartella META-INF (o in/share/using Linux). Questa cartella META-INF contiene una cartella AIR, che contiene un file "application.xml". Questo file contiene un tag <id />
che definisce l'identificativo dell'applicazione, utilizzato nel calcolo dell'identificatore mutex. Se l'applicazione può scrivere nella cartella di installazione, è possibile utilizzare l'API File
per modificarla in fase di runtime, modificando in modo casuale il tag <id />
, consentendo l'esecuzione contemporanea di più processi della stessa applicazione.
Questo sta avendo alcuni fastidiosi effetti collaterali, come la creazione di una nuova cartella nella cartella File.applicationStorageDirectory
ogni volta. Ma usando lo LocalConnection
, puoi minimizzare questo riutilizzando lo stesso identificatore più volte registrando quali sono liberi di essere riutilizzati. Inoltre, SharedObject
sono memorizzati in questa cartella, quindi non possono essere utilizzati (o devono essere copiati ogni volta che viene creata una nuova istanza e sincronizzati tramite LocalConnection
).
Per quanto ne so, Adobe non ha intenzione di rimuovere questa limitazione nativa. È stato implementato per scopi multipiattaforma, in particolare su MacOS, dove il dock lo rende più complicato (non è molto semplice avviare la stessa applicazione due volte con il dock).
Il modo ufficiale per farlo è catturare l'evento InvokeEvent.INVOKE
e fare cose come aprire una nuova finestra. E non c'è nessun cambiamento previsto per AIR 2.0 in questo comportamento.
Sarebbe d'aiuto se incapsulassi la logica della tua applicazione come una classe che potesse essere eseguita in una finestra e consentire all'utente di creare più istanze di quella finestra, all'interno di un'app? sarebbe d'aiuto?
Qual è il motivo principale per cui sono necessarie più applicazioni?
Grazie per la risposta, ma sono specificamente alla ricerca di processi separati. Esistono numerosi vantaggi, ad esempio l'esecuzione parallela su computer multiprocessore. – abc
Vedo, grazie per la spiegazione. Buona domanda. È possibile avere processi separati in Java ... questo potrebbe essere un modo prolisso, l'interfacciamento tra AIR e Java tramite Merapi (http://merapiproject.net/) può essere utile? –
Ancora, post interessante, ma è fuori tema. Merapi è un framework IPC piuttosto che un framework di collegamento (come JNI), quindi non è possibile collegarsi a una libreria java multi-thread; ci dovrebbe essere un processo java avviato separatamente. Inoltre, l'utilizzo di un helper java fornirebbe solo un'elaborazione parallela, non altri vantaggi di più processi. Torniamo alla domanda originale: sto cercando un modo per avviare diverse istanze di un'app Flex AIR, e in particolare se l'esecuzione dello stesso swf con più ID publisher è legale nel runtime AIR. – abc
Questo interromperà l'aggiornamento automatico, essere avvisati.
Il duplicatore di applicazioni aria vi aiuterà in questa parte. Usando questo puoi eseguire più istanze della stessa applicazione AIR.
https://github.com/chrisdeely/AirAppDuplicator
suo solo semplicemente copiare la directory app con nuovo nome e nuova applicazione id.
Ho appena fatto una lezione veloce per implementare la soluzione di Tyn. Basta chiamare. MultipleInstanceAirApp.changeMetaInfId(stage);
Non hai davvero bisogno della parte scenica, ma la uso per cambiare la posizione della finestra quando eseguo il test. Ad ogni modo, buon divertimento!
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) { }
}
}
}
Benvenuto in Stack Overflow! Sebbene questo snippet di codice sia benvenuto e possa fornire un aiuto, sarebbe [notevolmente migliorato se includesse una spiegazione] (// meta.stackexchange.com/q/114762) di * come * affronta la domanda. Senza di ciò, la tua risposta ha un valore educativo molto inferiore - ricorda che stai rispondendo alla domanda per i lettori in futuro, non solo per chi chiede ora! Si prega di [modificare] la risposta per aggiungere una spiegazione e fornire un'indicazione di quali limitazioni e ipotesi si applicano. –
- 1. Icone Adobe AIR 512x512?
- 2. Decompilazione applicazioni Adobe AIR
- 3. Silverlight vs Adobe Air
- 4. Strumenti di sviluppo per Adobe Flex/AIR?
- 5. Accesso alla porta seriale in Adobe-Air
- 6. Pensieri su Adobe AIR per Android?
- 7. come installare adobe air sdk in linux?
- 8. Adobe AIR e iPhone - come funziona?
- 9. Differenza tra Adobe AIR e FLEX?
- 10. Come riavviare un'applicazione autonoma Adobe Air/Flex
- 11. Applicazioni Adobe air multiple in un unico programma di installazione
- 12. Avvia attività dall'estensione nativa di Adobe AIR per Android
- 13. Installazione/aggiornamento dell'applicazione Adobe AIR non amministratore su Windows
- 14. Adobe AIR e diversi filesystem del sistema operativo
- 15. È possibile eseguire un'app Adobe AIR senza installazione?
- 16. Come scaricare e decomprimere la cartella .ZIP usando Adobe Air?
- 17. Adobe AIR: il touchscreen non attiva correttamente l'evento mouse down
- 18. Come inserire/salvare i file nella directory dell'applicazione? (adobe air)
- 19. Adobe AIR/FlashBuilder 4.6: Crea promemoria nell'app per Android
- 20. Errore ADL durante il caricamento del contenuto iniziale Adobe air
- 21. Cancellazione dell'eco acustico con Adobe Air sul cellulare
- 22. Ottieni l'altezza della tastiera in Adobe AIR Mobile
- 23. Ottieni il sistema operativo corrente in Adobe Air
- 24. Come usare canvas.toDataURL() per ottenere base64 dell'immagine in Adobe AIR?
- 25. Ottieni l'utente del sistema operativo connesso in Adobe Air
- 26. Rilevamento programmatico tra Adobe Air e Adobe Flex in ActionScript 3.0
- 27. Come impostare l'icona su un'applicazione Adobe Adobe
- 28. Le applicazioni Adobe AIR rallentano la risposta dopo i tempi di inattività
- 29. elemnts di ingresso in HTMLLoader sono di sola lettura in Adobe AIR
- 30. Quali versioni di Android e iOS sono compatibili con runtime captive Adobe AIR 3.0?
buone risposte si prega di guadagnare la taglia. – abc