Paket | flash.system |
Klass | public final class Worker |
Arv | Worker EventDispatcher Object |
Språkversion: | ActionScript 3.0 |
Körningsmiljöversioner: | Flash Player 11.4, AIR 3.4 |
Med en arbetare kan du köra kod "i bakgrunden" samtidigt som andra åtgärder körs i annan arbetare (inklusive i swf-huvudfilens arbetare). I sammanhang där inte arbetare används kan vissa åtgärder, till exempel för att bearbeta stora mängder data i en slinga, ta så lång tid att utföra att de förhindrar huvudprogrammet att uppdatera skärmen tillräckligt snabbt. Detta kan leda till en ojämn ström till skärmen eller att bilden fryses.
Med hjälp av arbetare kan du utföra en omfattande körning eller en långsam åtgärd i bakgrunden. I varje arbetare körs koden i en separat köringstråd från andra arbetare. Kod som körs länge i en arbetare blockerar inte kod som körs i andra arbetare. I stället körs de båda koduppsättningarna parallellt. Detta innebär att en arbetare kan användas för att köra kod i bakgrunden medan huvudprogrammet är fritt att fortsätta uppdatera skärmen.
Den här funktionen som samtidigt kör flera uppsättningar med kodinstruktioner kallas för samtidighet (concurrency).
Obs! Att använda arbetare för samtidighet stöds i både Flash Player och i AIR på datorplattformar. För mobila plattformar stöds samtidighet i AIR på både Android och iOS. Du kan använda den statiska egenskapen isSupported för att kontrollera om samtidighet stöds innan du försöker använda den.
Du kan inte skapa arbetarförekomster direkt genom att anropa Worker()
-konstruktorn. I sammanhang där samtidighet med arbetare stöds skapas vid start automatiskt den arbetare som är associerad med SWF-huvudfilen, kallas även den primitiva arbetaren.
Ytterligare arbetare skapas med separata swf-filer. Om du vill skapa en ny instans av Worker-klassen, skickar du en ByteArray med byte för bakgrundsarbetarens swf-fil som ett argument till WorkerDomain-klassens createWorker()
-metod. Det finns tre vanliga sätt att få åtkomst till byte i en swf-fil för detta ändamål:
-
Använd metataggen [Embed] för att bädda in swf-filen i programmet som en ByteArray:
// Embed the SWF file [Embed(source="../swfs/BgWorker.swf", mimeType="application/octet-stream")] private static var BgWorker_ByteClass:Class; private function createWorker():void { // create the background worker var workerBytes:ByteArray = new BgWorker_ByteClass(); var bgWorker:Worker = WorkerDomain.current.createWorker(workerBytes); // listen for worker state changes to know when the worker is running bgWorker.addEventListener(Event.WORKER_STATE, workerStateHandler); // set up communication between workers using // setSharedProperty(), createMessageChannel(), etc. // ... (not shown) bgWorker.start(); }
-
Läs in en extern SWF-fil med en URLLoader:
// load the SWF file var workerLoader:URLLoader = new URLLoader(); workerLoader.dataFormat = URLLoaderDataFormat.BINARY; workerLoader.addEventListener(Event.COMPLETE, loadComplete); workerLoader.load(new URLRequest("BgWorker.swf")); private function loadComplete(event:Event):void { // create the background worker var workerBytes:ByteArray = event.target.data as ByteArray; var bgWorker:Worker = WorkerDomain.current.createWorker(workerBytes); // listen for worker state changes to know when the worker is running bgWorker.addEventListener(Event.WORKER_STATE, workerStateHandler); // set up communication between workers using // setSharedProperty(), createMessageChannel(), etc. // ... (not shown) bgWorker.start(); }
-
Använd en SWF-fil eftersom både den primitiva arbetaren och bakgrundsarbetaren:
// The primordial worker's main class constructor public function PrimordialWorkerClass() { init(); } private function init():void { var swfBytes:ByteArray = this.loaderInfo.bytes; // Check to see if this is the primordial worker if (Worker.current.isPrimordial) { // create a background worker var bgWorker:Worker = WorkerDomain.current.createWorker(swfBytes); // listen for worker state changes to know when the worker is running bgWorker.addEventListener(Event.WORKER_STATE, workerStateHandler); // set up communication between workers using // setSharedProperty(), createMessageChannel(), etc. // ... (not shown) bgWorker.start(); } else // entry point for the background worker { // set up communication between workers using getSharedProperty() // ... (not shown) // start the background work } }
Arbetare som körs oberoende av varandra och som inte har åtkomst till samma minne, variabler och kod. Det finns emellertid tre metoder tillgängliga för att skicka meddelanden och data mellan Worker-förekomster.
- Delade egenskaper: Varje arbetare har en intern uppsättning namngivna värden som kan ställas in och läsas från själva arbetaren samt från andra arbetare. Du kan ställa in ett värde med metoden
setSharedProperty()
och läsa värdet med metodengetSharedProperty()
. - MessageChannel: Med ett MessageChannel-objekt kan du skicka envägsmeddelanden och data från en arbetare till en annan. Kod i den mottagande arbetaren kan lyssna efter en händelse för att få reda på när ett meddelande anländer. Om du vill skapa ett MessageChannel-objekt ska du använda metoden
createMessageChannel()
. - Delbar ByteArray: Om ByteArray-objektets
shareable
-egenskap ärtrue
, används samma underliggande minne för instanser av denna ByteArray i alla arbetare. Eftersom koden i flera arbetare har åtkomst till det delade minnet samtidigt, måste du i koden använda den metod som beskrivs i egenskapsbeskrivningen förByteArray.shareable
för att undvika problem med oväntade dataändringar.
Flera körtids-API:er är inte tillgängliga i kod som körs i bakgrunden. Dessa består primärt av API:er relaterade till metoder för användarindata och -utdata eller till operativsystemselement, såsom fönster och draoperationer. Som regel gäller att du för API:er som inte stöds i alla sammanhang ska använda isSupported
, available
och liknande egenskaper för att kontrollera om API:n är tillgänglig i bakgrundsarbetarens sammanhang innan du försöker använda API:n.
Obs! ANE-tillägg stöds inte för bakgrundsarbetare och sekundära arbetare.
Arbetare är värdefulla eftersom de minskar riskerna för bildrutebortfall på grund av att huvudåtergivningstråden blockerats av annan kod. Emellertid kräver arbetare mer systemminne och processorkapacitet vilket kan påverka programmets generella prestanda negativt. Eftersom varje arbetare använder egna instanser av den virtuella miljön kan även pålägget för en enkel arbetare vara stort. När du använder arbetare ska du testa koden på alla målplattformar för att försäkra dig om att inte belastningen på systemet blir för stor. Adobe rekommenderar att du använder mer än en eller två bakgrundsarbetare i vanliga situationer.
Lär dig mer
Introduktion till AS3-arbetare: Bildbehandling av Shawn Blais
Flertrådsfysik: Använda AS3-arbetare för en fysikmotor av Shawn Blais
Relaterade API-element
Egenskap | Definieras med | ||
---|---|---|---|
constructor : Object
En referens till klassobjektet eller konstruktorfunktionen för en given objektinstans. | Object | ||
current : Worker [statisk] [skrivskyddad]
Ger åtkomst till arbetaren som innehåller den aktuella koden
| Worker | ||
isPrimordial : Boolean [skrivskyddad]
Anger om arbetaren är den primitiva arbetaren. | Worker | ||
isSupported : Boolean [statisk] [skrivskyddad]
Anger om det aktuella miljösammanhanget har stöd för Worker-objekten vid samtidig kodkörning. | Worker | ||
state : String [skrivskyddad]
Det aktuella läget för arbetaren under dess livscykel. | Worker |
Metod | Definieras med | ||
---|---|---|---|
addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void [åsidosätt]
Registrerar ett händelseavlyssnarobjekt för ett EventDispatcher-objekt så att avlyssnaren får meddelanden om händelser. | Worker | ||
Skapar en ny MessageChannel-instans för att skicka meddelanden från arbetaren som metoden anropas från till en annan mottagande arbetare. | Worker | ||
Skickar en händelse till händelseflödet. | EventDispatcher | ||
Erhåller ett värde som lagras i den här arbetaren med en namngiven nyckel. | Worker | ||
Kontrollerar om EventDispatcher-objektet har några avlyssnare registrerade för en viss typ av händelse. | EventDispatcher | ||
Anger om det finns en egenskap angiven för ett objekt. | Object | ||
Anger om en instans av klassen Object finns i prototypkedjan för objektet som anges som parameter. | Object | ||
Anger om den angivna egenskapen finns och är uppräkningsbar. | Object | ||
[åsidosätt]
Tar bort en avlyssnare från EventDispatcher-objektet. | Worker | ||
Anger tillgänglighet för en dynamisk egenskap för slingåtgärder. | Object | ||
Tillhandahåller ett namngivet värde som är tillgängligt för kod som körs i arbetarens swf-fil. | Worker | ||
Startar körningen av arbetaren. | Worker | ||
Stoppar kodkörningen för den här arbetaren. | Worker | ||
Returnerar det här objektets strängrepresentation, formaterad i enlighet med språkspecifika konventioner. | Object | ||
Returnerar det angivna objektets strängbeteckning. | Object | ||
Returnerar det angivna objektets primitiva värde. | Object | ||
Kontrollerar om en händelseavlyssnare är registrerad för det här EventDispatcher-objektet eller något av dess överordnade objekt för den angivna händelsetypen. | EventDispatcher |
Händelse | Sammanfattning | Definieras med | ||
---|---|---|---|---|
[utsändningshändelse] Skickas när Flash Player eller AIR får operativsystemfokus och blir aktivt. | EventDispatcher | |||
[utsändningshändelse] Skickas när Flash Player eller AIR förlorar operativsystemfokus och blir inaktivt. | EventDispatcher | |||
Skickas när värdet på arbetarens state-egenskap ändras. | Worker |
current | egenskap |
isPrimordial | egenskap |
isPrimordial:Boolean
[skrivskyddad] Språkversion: | ActionScript 3.0 |
Körningsmiljöversioner: | Flash Player 11.4, AIR 3.4 |
Anger om arbetaren är den primitiva arbetaren.
Den primitiva arbetaren är arbetaren i vilken den inledande swf-filen körs. Denna arbetare kontrollerar återgivningen på skärmen.
Denna egenskap kan användas för att utforma ett program där den primitiva arbetaren och bakgrundsarbetaren är två instanser av samma swf-fil. Alternativet är att strukturera koden så att bakgrundsarbetaren använder en annan kod komplierad i en annan swf-fil än den primitiva arbetaren.
Implementering
public function get isPrimordial():Boolean
isSupported | egenskap |
isSupported:Boolean
[skrivskyddad] Språkversion: | ActionScript 3.0 |
Körningsmiljöversioner: | Flash Player 11.4, AIR 3.4 |
Anger om det aktuella miljösammanhanget har stöd för Worker-objekten vid samtidig kodkörning.
Om samtidighet är tillgänglig är detta egenskapsvärde true
.
Implementering
public static function get isSupported():Boolean
state | egenskap |
state:String
[skrivskyddad] Språkversion: | ActionScript 3.0 |
Körningsmiljöversioner: | Flash Player 11.4, AIR 3.4 |
Det aktuella läget för arbetaren under dess livscykel. Möjliga värden för den här egenskapen definieras i klassen WorkerState.
Implementering
public function get state():String
Relaterade API-element
addEventListener | () | metod |
override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
Språkversion: | ActionScript 3.0 |
Körningsmiljöversioner: | Flash Player 11.4, AIR 3.4 |
Registrerar ett händelseavlyssnarobjekt för ett EventDispatcher-objekt så att avlyssnaren får meddelanden om händelser. Du kan registrera händelseavlyssnare på alla noder i visningslistan efter en särskild typ av händelse, fas och prioritet.
När du har registrerat en händelseavlyssnare går det inte att ändra dess prioritet genom ytterligare anrop till addEventListener()
. För att kunna ändra avlyssnarens prioritet måste du först anropa removeListener()
. Sedan går det att registrera avlyssnaren på nytt med den nya prioritetsnivån.
Kom ihåg att när avlyssnaren har registrerats så skapar anrop till addEventListener()
med annan type
eller useCapture
-värde en separat avlyssnarregistrering. Om du till exempel först registrerar en avlyssnare med useCapture
inställt på true
, avlyssnar den bara under hämtningsfasen. Om du anropar addEventListener()
igen med samma avlyssningsobjekt men med useCapture
inställt på false
, får du två separata avlyssnare: en som avlyssnar under hämtningsfasen och en som avlyssnar under både mål- och bubblingsfasen.
Det går inte att registrera en händelseavlyssnare endast för målfasen eller bubblingsfasen. De faserna är sammankopplade vid registreringen eftersom bubblande bara tillämpas på de som är överordnade målnoden.
Om du inte längre behöver en händelseavlyssnare tar du bort den genom att anropa removeEventListener()
. Annars finns risk för minnesproblem. Händelseavlyssnare tas inte automatiskt bort från minnet, eftersom skräpinsamlaren inte tar bort avlyssnaren så länge det skickande objektet finns (om inte parametern useWeakReference
är true
).
Kopiering av en EventDispatcher-instans innebär inte att de händelseavlyssnare som är kopplade till den kopieras. (Om en nod som du nyss skapat behöver en händelseavlyssnare måste du koppla avlyssnaren efter att du skapat noden.) Om du däremot flyttar en EventDispatcher-instans flyttas den kopplade händelseavlyssnaren med.
Om händelseavlyssnaren är registrerad på en nod samtidigt som en händelse bearbetas på den noden aktiveras inte händelseavlyssnaren under den aktuella fasen, men den kan aktiveras under en senare fas i händelseflödet, t.ex. bubblingsfasen.
Om en händelseavlyssnare tas bort från en nod samtidigt som en händelse bearbetas på den noden, aktiveras den ändå av de aktuella åtgärderna. När händelseavlyssnaren tagits bort anropas den aldrig mer (om den inte registreras på nytt för framtida bearbetning).
Parametrar
type:String — Händelsens typ.
| |
listener:Function — Avlyssnarfunktionen som bearbetar händelsen. Den här funktionen måste acceptera ett Event-objekt som sin enda parameter och får inte returnera någonting, se följande exempel:
function(evt:Event):void Funktionen kan ha vilket namn som helst. | |
useCapture:Boolean (default = false ) —
Avgör om avlyssnaren fungerar i hämtningsfasen eller mål- och bubblingsfaserna. Om useCapture är inställd på true bearbetar avlyssningsprocessen bara händelsen under hämtningsfasen och inte under mål- eller bubblingsfasen. Om useCapture är inställd på false bearbetar avlyssningsprocessen bara händelsen under mål- och bubblingsfasen. Om du vill avlyssna händelsen under alla tre faserna anropar du addEventListener två gånger, en gång med useCapture inställd på true , och sedan en gång med useCapture inställd på false .
| |
priority:int (default = 0 ) — Händelseavlyssnarens prioritetsnivå. Prioriteten anges av ett 32-bitars heltal med tecken. Ju högre tal, desto högre prioritet. Alla avlyssnare med prioritet n bearbetas före avlyssnare med prioritet n -1. Om två eller fler avlyssnare har samma prioritet bearbetas de i den ordning de lades till. Standardprioritet är 0.
| |
useWeakReference:Boolean (default = false ) — Avgör om referensen till avlyssnaren är stark eller svag. En stark referens (standard) förhindrar att avlyssnaren skräpsamlas. Det gör inte en svag referens. Medlemsfunktioner på klassnivå skräpsamlas inte, så du kan ange |
createMessageChannel | () | metod |
public function createMessageChannel(receiver:Worker):MessageChannel
Språkversion: | ActionScript 3.0 |
Körningsmiljöversioner: | Flash Player 11.4, AIR 3.4 |
Skapar en ny MessageChannel-instans för att skicka meddelanden från arbetaren som metoden anropas från till en annan mottagande arbetare. Kod i arbetaren som skapar MessageChannel-objektet kan använda den för att skicka envägsmeddelanden till det Worker-objekt som anges i receiver
-argumentet.
Trots att en MessageChannel-instans kan användas för att skicka meddelanden och data från en Worker-instans till en annan, måste minst en MessageChannel-instans skickas till en underordnad Worker-instans som en delad egenskap genom att anropa Worker-objektets setSharedProperty()
-metod.
outgoingChannel = Worker.current.createMessageChannel(bgWorker); incomingChannel = bgWorker.createMessageChannel(Worker.current); bgWorker.setSharedProperty("incoming", outgoingChannel); bgWorker.setSharedProperty("outgoing", incomingChannel); // listen for messages from the receiving MessageChannel // This event is triggered when the background sends a message to this worker incomingChannel.addEventListener(Event.CHANNEL_MESSAGE, incomingMessageHandler);
Parametrar
receiver:Worker — Arbetaren som kommer att ta emot meddelanden överförda via den skapade meddelandekanalen.
|
MessageChannel — MessageChannel-objektet som skapads av en åtgärd
|
getSharedProperty | () | metod |
public function getSharedProperty(key:String):*
Språkversion: | ActionScript 3.0 |
Körningsmiljöversioner: | Flash Player 11.4, AIR 3.4 |
Erhåller ett värde som lagras i den här arbetaren med en namngiven nyckel.
Koden i en underordnad arbetare kan anropa den här metoden för att hämta ett värde så tidigt som möjligt i konstruktorn för arbetar-swf-filens huvudklass.
Parametrar
key:String — Namnet på den delade egenskapen som ska hämtas
|
* — Det delade egenskapsvärdet som lagrats med den angivna nyckeln eller null om inget värde lagras för den angivna nyckeln
|
removeEventListener | () | metod |
override public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
Språkversion: | ActionScript 3.0 |
Körningsmiljöversioner: | Flash Player 11.4, AIR 3.4 |
Tar bort en avlyssnare från EventDispatcher-objektet. Ett anrop till den här metoden har ingen effekt om det inte finns någon matchande avlyssnare registrerad för EventDispatcher-objektet.
Parametrar
type:String — Händelsens typ.
| |
listener:Function — Det avlyssnarobjekt som ska tas bort.
| |
useCapture:Boolean (default = false ) —
Anger om avlyssnaren registrerades för hämtningsfasen eller mål- och bubblingsfaserna. Om avlyssnaren registrerades både för hämtningsfasen och mål- och bubblingsfaserna krävs två anrop till removeEventListener() för att båda ska tas bort: ett anrop med useCapture() inställt på true och ett annat anrop med useCapture() inställt på false .
|
setSharedProperty | () | metod |
public function setSharedProperty(key:String, value:*):void
Språkversion: | ActionScript 3.0 |
Körningsmiljöversioner: | Flash Player 11.4, AIR 3.4 |
Tillhandahåller ett namngivet värde som är tillgängligt för kod som körs i arbetarens swf-fil.
Du kan anropa den här metoden innan du anropar arbetarens start()
-metod. I detta fall är den delade egenskapen tillgänglig för kod i arbetarens swf-fil vid konstruktionen.
Värdet som skickas till parametern value
kan näst intill vara vilket objekt som helst. Förutom undantagen enligt nedan skickas inte alla objekt till parametern value
som referens. Alla ändringar som görs av objektet i en arbetare, efter det att setSharedProperty()
har anropats, vidarekopplas inte till den andra arbetaren. Objektet kopieras genom att det serialiseras till AMF3-format och avserialiseras till ett nytt objekt i den mottagande arbetaren. Detta medför att objekt som inte kan serialiseras till AMF3-format, inklusive visningsobjekt, inte kan skickas till parametern value
. För att en anpassad klass ska kunna skickas måste klassdefinitionen registreras med flash.net.registerClassAlias()
-funktionen eller med [RemoteClass]
-metadata. Oberoende av teknik måste samma alias användas för båda arbetarnas versioner av klassen.
Det finns fem typer av objekt som utgör undantag från regeln att objekt inte delas mellan arbetare:
- Arbetare
- MessageChannel
- Delbar ByteArray (ett ByteArray-objekt med dess
shareable
-egenskap inställd påtrue
- Mutex
- Condition
Om du skickar en instans av dessa objekt till parametern value
får varje arbetare en referens till samma underliggande objekt. Ändringar gjorda i en instans i en arbetare är omedelbart tillgängliga i en annan arbetare. Om du dessutom skickar samma instans av dessa objekt mer än en gång med setSharedProperty()
, kommer ingen ny kopia av objektet att skapas för den mottagande arbetaren i miljön. I stället återanvänds samma referens för att minimera systemminnesbelastningen.
Genom att anropa den här metoden med null
eller undefined
för argumentet value
rensas eventuella tidigare inställda värden för det angiva argumentet key
. Att rensa ett värde på detta sätt tar bort referensen till det, vilket medför att det kan skräpinsamlas.
Du kan använda valfritt strängvärde i key-argumentet. Dessa delade egenskaper är tillgängliga för kod som har åtkomst till en arbetare. Om du vill undvika att oavsiktligt skriva över ett värde bör du överväga att använda ett prefix, suffix eller liknande för att försöka göra key-namnen unika.
Parametrar
key:String — Namnet under vilket den delade egenskapen lagras.
| |
value:* — Värdet på den delade egenskapen.
|
Relaterade API-element
start | () | metod |
public function start():void
Språkversion: | ActionScript 3.0 |
Körningsmiljöversioner: | Flash Player 11.4, AIR 3.4 |
Startar körningen av arbetaren. I miljön skapas arbetartråden och konstruktorn för arbetar-swf-filens huvudklass anropas.
Den här åtgärden är asynkron. När arbetaren har startats ändras dess state
-egenskap till WorkerState.RUNNING
och en workerState
-händelse skickas.
terminate | () | metod |
public function terminate():Boolean
Språkversion: | ActionScript 3.0 |
Körningsmiljöversioner: | Flash Player 11.4, AIR 3.4 |
Stoppar kodkörningen för den här arbetaren. Genom att anropa den här metoden avbryts aktuella ActionScript i arbetarens swf-fil.
ReturnerarBoolean — true om koden i arbetaren kördes och avbröts, eller false om arbetaren aldrig startades
|
workerState | Händelse |
flash.events.Event
egenskap Event.type =
flash.events.Event.WORKER_STATE
Språkversion: | ActionScript 3.0 |
Körningsmiljöversioner: | Flash Player 11.4, AIR 3.4 |
Skickas när värdet på arbetarens state
-egenskap ändras.
Event.WORKER_STATE
-konstanten definierar värdet på type
-egenskapen i ett workerState
-händelseobjekt.
Den här händelsen har följande egenskaper:
Egenskap | Värde |
---|---|
bubbles | false |
cancelable | false ; det finns inget standardbeteende att avbryta. |
currentTarget | Det objekt som aktivt behandlar Event-objektet med en händelseavlyssnare. |
target | Det objekt som skickade den här händelsen. |
Exemplet består av tre ActionScript-klasser: WorkerExample är huvudklassen och den överordnade arbetaren. BackgroundWorker är klassen som arbetar i bakgrunden. Den är sammanställd av huvudklassen för bakgrundsarbetarens swf-fil. CountResult är en anpassad klass som används för att skicka data mellan de båda arbetarna som ett enskilt objekt i stället för som flera värden.
I detta exempel räknar en bakgrundsarbetare i en slinga upp till det antal som angivits i den överordnade arbetaren. Medan förloppet pågår skickas statusmeddelanden till den överordnade arbetaren. När så uppräkningen är klar skickar bakgrundsarbetaren ett meddelande till den överordnade arbetaren för att meddela att uppräkningen är klar och för att ange hur lång tid det tog.
Klassen WorkerExample är huvudklassen för swf-filen så den blir huvudklass för den primitiva arbetaren. I metoden initialize()
skapar koden bakgrundsarbetarobjektet med hjälp av byte för BackgroundWorker-klassen, vilken är inbäddad med en [Embed]
-tagg.
När bakgrundsarbetaren har skapats med anrop av WorkerDomain.createWorker()
, upprättar koden kommunikationen mellan de båda arbetarna. Till att börja med skapar koden en uppsättning MessageChannel-objekt. De skickas tillbaka till bakgrundsarbetaren genom att dess setSharedProperty()
-metod anropas. Slutligen registreras workerState
-händelsen för bakgrundsarbetarens objektshändelse och arbetaren startas genom ett anrop av dess start()
-metod.
Medan bakgrundsarbetaren utför sitt arbete skickas förloppsmeddelanden (och eventuella resultat) till den överordnade arbetaren. Den överordnade arbetaren använder den här informationen för att uppdatera förloppsfältet och textindikatorn.
package { import com.adobe.example.vo.CountResult; import flash.display.Shape; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.net.registerClassAlias; import flash.system.MessageChannel; import flash.system.Worker; import flash.system.WorkerDomain; import flash.system.WorkerState; import flash.text.TextField; import flash.text.TextFormat; import flash.text.TextFormatAlign; import flash.utils.ByteArray; public class WorkerExample extends Sprite { // ------- Embed the background worker swf as a ByteArray ------- [Embed(source="../workerswfs/BackgroundWorker.swf", mimeType="application/octet-stream")] private static var BackgroundWorker_ByteClass:Class; public static function get BackgroundWorker():ByteArray { return new BackgroundWorker_ByteClass(); } private var bgWorker:Worker; private var bgWorkerCommandChannel:MessageChannel; private var progressChannel:MessageChannel; private var resultChannel:MessageChannel; public function WorkerExample() { initialize(); } private function initialize():void { // create the user interface setupStage(); createStatusText(); createProgressBar(); // Register the alias so we can pass CountResult objects between workers registerClassAlias("com.adobe.test.vo.CountResult", CountResult); // Create the background worker bgWorker = WorkerDomain.current.createWorker(BackgroundWorker); // Set up the MessageChannels for communication between workers bgWorkerCommandChannel = Worker.current.createMessageChannel(bgWorker); bgWorker.setSharedProperty("incomingCommandChannel", bgWorkerCommandChannel); progressChannel = bgWorker.createMessageChannel(Worker.current); progressChannel.addEventListener(Event.CHANNEL_MESSAGE, handleProgressMessage) bgWorker.setSharedProperty("progressChannel", progressChannel); resultChannel = bgWorker.createMessageChannel(Worker.current); resultChannel.addEventListener(Event.CHANNEL_MESSAGE, handleResultMessage); bgWorker.setSharedProperty("resultChannel", resultChannel); // Start the worker bgWorker.addEventListener(Event.WORKER_STATE, handleBGWorkerStateChange); bgWorker.start(); } private function handleBGWorkerStateChange(event:Event):void { if (bgWorker.state == WorkerState.RUNNING) { _statusText.text = "Background worker started"; bgWorkerCommandChannel.send(["startCount", 100000000]); } } private function handleProgressMessage(event:Event):void { var percentComplete:Number = progressChannel.receive(); setPercentComplete(percentComplete); _statusText.text = Math.round(percentComplete).toString() + "% complete"; } private function handleResultMessage(event:Event):void { var result:CountResult = resultChannel.receive() as CountResult; setPercentComplete(100); _statusText.text = "Counted to " + result.countTarget + " in " + (Math.round(result.countDurationSeconds * 10) / 10) + " seconds"; } // ------- Create UI ------- private var _currentPercentComplete:int = 0; private var _needsValidation:Boolean = false; private var _statusText:TextField; private var _progressBarRect:Shape; private var _progressBar:Shape; private function setupStage():void { stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; stage.stageWidth = 800; stage.stageHeight = 600; stage.color = 0xffffff; } private function createStatusText():void { _statusText = new TextField(); _statusText.width = 400; _statusText.height = 25; _statusText.x = (stage.stageWidth - _statusText.width) / 2; _statusText.y = 150; var statusTextFormat:TextFormat = new TextFormat(); statusTextFormat.color = 0xeeeeee; statusTextFormat.font = "Verdana"; statusTextFormat.align = TextFormatAlign.CENTER; statusTextFormat.size = 16; _statusText.defaultTextFormat = statusTextFormat; _statusText.wordWrap = false; _statusText.opaqueBackground = 0x999999; _statusText.selectable = false; _statusText.text = "Initializing..."; addChild(_statusText); } private function createProgressBar():void { _progressBarRect = new Shape(); _progressBarRect.graphics.beginFill(0x000000, 0); _progressBarRect.graphics.lineStyle(2, 0x000000); _progressBarRect.graphics.drawRect(0, 0, 400, 30); _progressBarRect.graphics.endFill(); _progressBarRect.x = (stage.stageWidth - _progressBarRect.width) / 2; _progressBarRect.y = 100; addChild(_progressBarRect); _progressBar = new Shape(); _progressBar.graphics.beginFill(0x0000ee); _progressBar.graphics.drawRect(0, 0, 391, 21); _progressBar.x = _progressBarRect.x + 4; _progressBar.y = _progressBarRect.y + 4; addChild(_progressBar); _progressBar.scaleX = 0; } private function setPercentComplete(percentComplete:int):void { if (_currentPercentComplete == percentComplete) return; _currentPercentComplete = percentComplete; invalidateValue(); } private function invalidateValue():void { if (_needsValidation) return; _needsValidation = true; addEventListener(Event.EXIT_FRAME, validate); } private function validate(event:Event):void { removeEventListener(Event.EXIT_FRAME, validate); _needsValidation = false; _redrawProgressBar(); } private function _redrawProgressBar():void { _progressBar.scaleX = _currentPercentComplete / 100; } } }
I metoden initialize()
tas de MessageChannel-objekt, som den överordnade arbetaren skickade, emot. De används för kommunikationen mellan de båda arbetarna.
Den överordnade arbetaren anropar send()
-metoden på commandChannel
-meddelandekanalen för att skicka ett meddelande. I bakgrundsarbetaren skickas sedan channelMessage
-händelsen genom att handleCommandMessage()
-metoden anropas.
Bakgrundsarbetarens faktiska arbete sker i metoden count()
. Medan uppräkningen fortsätter i bakgrundsarbetaren skickas förloppsmeddelanden till den överordnade send()
-metoden på MessageChannel-objektet för progressChannel
. När uppräkningen är klar anropas metoden send()
på MessageChannel-objektet för resultChannel
.
package com.adobe.example.workers { import com.adobe.example.vo.CountResult; import flash.display.Sprite; import flash.events.Event; import flash.net.registerClassAlias; import flash.system.MessageChannel; import flash.system.Worker; import flash.utils.getTimer; public class BackgroundWorker extends Sprite { private var commandChannel:MessageChannel; private var progressChannel:MessageChannel; private var resultChannel:MessageChannel; public function BackgroundWorker() { initialize(); } private function initialize():void { registerClassAlias("com.adobe.test.vo.CountResult", CountResult); // Get the MessageChannel objects to use for communicating between workers // This one is for receiving messages from the parent worker commandChannel = Worker.current.getSharedProperty("incomingCommandChannel") as MessageChannel; commandChannel.addEventListener(Event.CHANNEL_MESSAGE, handleCommandMessage); // These are for sending messages to the parent worker progressChannel = Worker.current.getSharedProperty("progressChannel") as MessageChannel; resultChannel = Worker.current.getSharedProperty("resultChannel") as MessageChannel; } private function handleCommandMessage(event:Event):void { if (!commandChannel.messageAvailable) return; var message:Array = commandChannel.receive() as Array; if (message != null && message[0] == "startCount") { count(uint(message[1])); } } private function count(targetValue:uint):void { var startTime:int = getTimer(); var onePercent:uint = uint(Math.ceil(targetValue / 100)); var oneHalfPercent:Number = onePercent / 2; var i:uint = 0; while (i < targetValue) { i++; // only send progress messages every one-half-percent milestone // to avoid flooding the message channel if (i % oneHalfPercent == 0) { progressChannel.send(i / onePercent); } } var elapsedTime:int = getTimer() - startTime; var result:CountResult = new CountResult(targetValue, elapsedTime / 1000); resultChannel.send(result); trace("counted to", targetValue.toString(), "in", elapsedTime, "milliseconds"); } } }
registerClassAlias()
med samma aliasnamn.
package com.adobe.example.vo { public class CountResult { public function CountResult(countTarget:uint=0, countTime:Number=0) { this.countTarget = countTarget; this.countDurationSeconds = countTime; } public var countTarget:uint; public var countDurationSeconds:Number; } }
1. Eftersom dynamisk inläsning av en SWF-fjärrfil som innehåller ActionScript-kod inte fungerar, måste SWF-fjärrfilen överföras till Worker som en rensad SWF-fil. 2. Det går inte att bädda in SWF-filer (med ABC-kod) med taggen [Embed] i iOS. Ytterligare arbetare skapas från en separat SWF-fil. Om du vill skapa en ny instans av Worker-klassen, skickar du en ByteArray med byte för bakgrundsarbetarens SWF-fil som ett argument till WorkerDomain-klassens createWorker()
-metod.
Det finns två vanliga sätt att komma åt byten i en SWF-fil för detta ändamål i iOS: Det första sättet är att läsa in en extern SWF-fil med loader
och det andra är att läsa in SWF-filen med URLLoader
.
I följande exempel används API:n Loader
för att läsa in SWF-filen.
package { import flash.display.Loader; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.IOErrorEvent; import flash.net.URLRequest; import flash.system.ApplicationDomain; import flash.system.LoaderContext; import flash.system.MessageChannel; import flash.system.Worker; import flash.system.WorkerDomain; import flash.text.TextField; import flash.text.TextFormat; public class IOSWorkerExample extends Sprite { public var worker:Worker; public var bm:MessageChannel; public var mb:MessageChannel; public var tf:TextField; public var tfrmt:TextFormat; public function IOSWorkerExample() { super(); stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; tf=new TextField(); tfrmt= new TextFormat() tfrmt.size=80; tf.textColor = 0xFFFFF; tf.defaultTextFormat=tfrmt; addChild(tf); //creating the urlRequest object that references the background worker. var _urlRequest:URLRequest = new URLRequest("IOSBackWorker.swf"); var _loader:Loader = new Loader(); var _lc:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain, null); _loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler); _loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,errorHandler); _loader.load(_urlRequest, _lc); } // This function is called once the swf loading is completed public function completeHandler(e:Event):void { worker = WorkerDomain.current.createWorker(e.target.bytes); bm = worker.createMessageChannel(Worker.current); mb = Worker.current.createMessageChannel(worker); worker.setSharedProperty("btm", bm); worker.setSharedProperty("mtb", mb); //adding event handler on message receive from background bm.addEventListener(Event.CHANNEL_MESSAGE, onBackToMain); worker.start(); bm.receive(true); } public function errorHandler(e:IOErrorEvent):void { trace("In IO ErrorEvent Handler "+e.text); } //This function is called when the main thread receives the message from the background worker. public function onBackToMain(event:Event):void { if(bm.messageAvailable) { // displaying the percentages based on the message received from the background. var progress:Number = bm.receive(); trace("progress "+progress); tf.text= progress.toString(); } } } }
Loader
anropas, måste egenskapskontrollen isPrimordial
användas i bakgrundsarbetaren, så som visas i exemplet.
package { import flash.display.Sprite; import flash.system.MessageChannel; import flash.system.Worker; import flash.utils.ByteArray; import flash.utils.getTimer; public class IOSBackWorker extends Sprite { private var memory:ByteArray = new ByteArray(); private var bm:MessageChannel; private var mb:MessageChannel; public function IOSBackWorker() { if(!Worker.current.isPrimordial) { memory.shareable = true; // creating objects of message channels bm = Worker.current.getSharedProperty("btm"); mb = Worker.current.getSharedProperty("mtb"); // calculating the percentage trace("message came"); var j:Number =1; while (j<1000) { for(var i=0;i<100;i++){} var startTime=getTimer(); // adding delay while (getTimer()-startTime <100); trace(j, (100*j)/1000); var progress:Number=(100*j)/1000; // sending the percentage to the main thread bm.send(progress); j++; } } } } }
Tue Jun 12 2018, 01:40 PM Z