Implementera gränssnittet IFilePromiseAdobe AIR 2 och senare Om du vill ange fillöften för resurser som inte kan kommas åt med hjälp av ett URLFilePromise-objekt kan du implementera gränssnittet IFilePromise i en anpassad klass. Gränssnittet IFilePromise anger vilka metoder och egenskaper som används av AIR-körningen för att komma åt data som ska skrivas till en fil när fillöften släpps. En IFilePromise-implementering skickar ett annat objekt till AIR-körningen som tillhandahåller data för fillöftet. Objektet måste implementera gränssnittet IDataInput som används av AIR-körningen för att läsa data. Klassen URLFilePromise som implementerar IFilePromise använder till exempel ett URLStream-objekt som dataleverantör. I AIR kan data läsas synkront eller asynkront. IFilePromise-implementeringen rapporterar vilket åtkomstläge som stöds genom att returnera korrekt värde i egenskapen isAsync. Om asynkron dataåtkomst tillhandahålls måste dataleverantörsobjektet implementera gränssnittet IEventDispatcher och skicka nödvändiga händelser som open, progress och complete. Som dataleverantör för ett fillöfte kan du använda en anpassad klass, eller någon av följande inbyggda klasser:
Om du vill implementera gränssnittet IFilePromise måste du ange kod för följande funktioner och egenskaper:
Alla IFilePromise-metoder anropas av körningen under en dra och släpp-åtgärd där fillöftet används. Programlogiken skulle normalt inte anropa någon av dessa metoder direkt. Använda en synkron dataleverantör i ett fillöfteDet enklaste sättet att implementera gränssnittet IFilePromise är genom att använda ett synkront dataleverantörsobjekt, till exempel ett ByteArray eller ett synkront FileStream. I följande exempel skapas ett ByteArray-objekt, fylls med data och returneras när metoden open() anropas. package { import flash.desktop.IFilePromise; import flash.events.ErrorEvent; import flash.utils.ByteArray; import flash.utils.IDataInput; public class SynchronousFilePromise implements IFilePromise { private const fileSize:int = 5000; //size of file data private var filePath:String = "SynchronousFile.txt"; public function get relativePath():String { return filePath; } public function get isAsync():Boolean { return false; } public function open():IDataInput { var fileContents:ByteArray = new ByteArray(); //Create some arbitrary data for the file for( var i:int = 0; i < fileSize; i++ ) { fileContents.writeUTFBytes( 'S' ); } //Important: the ByteArray is read from the current position fileContents.position = 0; return fileContents; } public function close():void { //Nothing needs to be closed in this case. } public function reportError(e:ErrorEvent):void { trace("Something went wrong: " + e.errorID + " - " + e.type + ", " + e.text ); } } } I praktiken är användbarheten för synkrona fillöften begränsad. Om mängden data är liten kan du lika enkelt skapa en fil i en tillfällig katalog och lägga till en vanlig fillistearray till Urklipp för dra och släpp. Det krävs däremot en lång synkron process om mängden data är stor, eller om det är resurskrävande att skapa dessa data. Långa synkrona processer kan blockera uppdateringar av användargränssnittet under märkbart lång tid och få det att verka som att programmet inte svarar. Om du vill undvika det här problemet kan du skapa en asynkron dataleverantör som styrs av en timer. Använda en asynkron dataleverantör i ett fillöfteNär du använder ett asynkront dataleverantörsobjekt måste IFilePromise-egenskapen isAsync vara true och objektet som returneras av metoden open() måste implementera gränssnittet IEventDispatcher. Körningen lyssnar efter flera alternativa händelser så att olika inbyggda objekt kan användas som dataleverantör. Till exempel skickas progress-händelser av FileStream- och URLStream-objekt, medan socketData-händelser skickas av Socket-objekt. Körningen lyssnar efter lämpliga händelser från alla dessa objekt. Följande händelser styr processen att läsa data från dataleverantörsobjektet:
Dataleverantören bör skicka de här händelserna i följande sekvens:
Obs! De inbyggda objekten FileStream, Socket, och URLStream skickar automatiskt de rätta händelserna.
I följande exempel skapas ett fillöfte med hjälp av en anpassad, asynkron dataleverantör. Dataleverantörsklassen utökar ByteArray-objektet (för IDataInput-stöd) och implementerar gränssnittet IEventDispatcher. Vid varje timerhändelse genererar objektet en mängd data och skickar en förloppshändelse för att informera körningen om att dessa data finns tillgängliga. När en tillräckligt stor mängd data har producerats skickar objektet en slutförandehändelse. package { import flash.events.Event; import flash.events.EventDispatcher; import flash.events.IEventDispatcher; import flash.events.ProgressEvent; import flash.events.TimerEvent; import flash.utils.ByteArray; import flash.utils.Timer; [Event(name="open", type="flash.events.Event.OPEN")] [Event(name="complete", type="flash.events.Event.COMPLETE")] [Event(name="progress", type="flash.events.ProgressEvent")] [Event(name="ioError", type="flash.events.IOErrorEvent")] [Event(name="securityError", type="flash.events.SecurityErrorEvent")] public class AsyncDataProvider extends ByteArray implements IEventDispatcher { private var dispatcher:EventDispatcher = new EventDispatcher(); public var fileSize:int = 0; //The number of characters in the file private const chunkSize:int = 1000; //Amount of data written per event private var dispatchDataTimer:Timer = new Timer( 100 ); private var opened:Boolean = false; public function AsyncDataProvider() { super(); dispatchDataTimer.addEventListener( TimerEvent.TIMER, generateData ); } public function begin():void{ dispatchDataTimer.start(); } public function end():void { dispatchDataTimer.stop(); } private function generateData( event:Event ):void { if( !opened ) { var open:Event = new Event( Event.OPEN ); dispatchEvent( open ); opened = true; } else if( position + chunkSize < fileSize ) { for( var i:int = 0; i <= chunkSize; i++ ) { writeUTFBytes( 'A' ); } //Set position back to the start of the new data this.position -= chunkSize; var progress:ProgressEvent = new ProgressEvent( ProgressEvent.PROGRESS, false, false, bytesAvailable, bytesAvailable + chunkSize); dispatchEvent( progress ) } else { var complete:Event = new Event( Event.COMPLETE ); dispatchEvent( complete ); } } //IEventDispatcher implementation public function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void { dispatcher.addEventListener( type, listener, useCapture, priority, useWeakReference ); } public function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void { dispatcher.removeEventListener( type, listener, useCapture ); } public function dispatchEvent(event:Event):Boolean { return dispatcher.dispatchEvent( event ); } public function hasEventListener(type:String):Boolean { return dispatcher.hasEventListener( type ); } public function willTrigger(type:String):Boolean { return dispatcher.willTrigger( type ); } } } Obs! Eftersom klassen AsyncDataProvider i exemplet utökar ByteArray, kan den inte också utöka EventDispatcher. Klassen använder ett internt EventDispatcher-objekt för att implementera gränssnittet IEventDispatcher och vidarebefordrar IEventDispatcher-metodanropen till det interna objektet. Du bör också utöka EventDispatcher och implementera IDataInput (eller implementera båda gränssnitten).
Den asynkrona implementeringen av IFilePromise är nästan identisk med den synkrona implementeringen. De viktigaste skillnaderna är att isAsync returnerar true och att metoden open() returnerar ett asynkront dataobjekt: package { import flash.desktop.IFilePromise; import flash.events.ErrorEvent; import flash.events.EventDispatcher; import flash.utils.IDataInput; public class AsynchronousFilePromise extends EventDispatcher implements IFilePromise { private var fileGenerator:AsyncDataProvider; private const fileSize:int = 5000; //size of file data private var filePath:String = "AsynchronousFile.txt"; public function get relativePath():String { return filePath; } public function get isAsync():Boolean { return true; } public function open():IDataInput { fileGenerator = new AsyncDataProvider(); fileGenerator.fileSize = fileSize; fileGenerator.begin(); return fileGenerator; } public function close():void { fileGenerator.end(); } public function reportError(e:ErrorEvent):void { trace("Something went wrong: " + e.errorID + " - " + e.type + ", " + e.text ); } } } |
![]() |
Upphovsrätt | Online Privacy Policy