1

I've got a code, which caches loaded resources (both images and swfs) and saves its bytes to flash SharedObject:

var cache:SharedObject = SharedObject.getLocal('dataCache');
cache.data[url] = (loader.contentLoaderInfo as LoaderInfo).bytes;

When there's a query to load new resource, the code checks if the resource is in cache and then loads its bytes:

var loader:FlexLoader = new FlexLoader();
// handlers skipped
var lc:LoaderContext = new LoaderContext();
lc.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);

if (cache && cache.data[url])
    loader.loadBytes(cache.data[url], lc)
else
    loader.load(new URLRequest(url), lc);

The problem: sometimes FlexLoader.loadBytes() loads PNGs and JPGs as MovieClip. I.e. when I look into loader.content on complete event I see MovieClip and in loader.contentLoaderInfo.contentType there's "application/x-shockwave-flash". (Sometimes means that such a behaviuor is reproduced on most computers and only after ".sol" file exceeds 9 Mb.)

Does anyone know how to make FlexLoader load proper content?

There's a hack to avoid such a behaviour, but it's quite ugly. Loaded MovieClip has inside itself only one child - the desired Bitmap, so I can check on resource type and extract graphic:

public function getAsBitmap(imgName:String):Bitmap
{
    var res:Object = getResource(imgName);
    if (res is MovieClip)
    {
        try
        {
            return (res as MovieClip).getChildAt(0) as Bitmap;
        }
        catch(e:*) {}
    }
    return res as Bitmap;
}
Benny
  • 2,250
  • 4
  • 26
  • 39
moropus
  • 3,672
  • 1
  • 22
  • 30

2 Answers2

1

Yeah, I have stumbled upon that problem too recently. Thing is the Loader class can be used as is to add its content to the scene because it loads a display object. It's not always convenient, however.

Use an URLLoader instead and set its data format as binary. You'll then be able to get the data correctly. If you absolutely need the FlexLoader, you can also loadBytes() the data from the URLLoader but I don't think that's necessary in your case.

private function loadFromDisk(url:String, loader:Loader):void
{
    var urlLoader:URLLoader = new URLLoader();
    var urlRequest:URLRequest = new URLRequest(url);

    urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
    urlLoader.addEventListener(Event.COMPLETE, loadComplete, false, 100, true);
    urlLoader.load(urlRequest);
}

private function loadComplete(event:Event):void
{
    var urlLoader:URLLoader = URLLoader(event.target);
    imageBytes:ByteArray = urlLoader.data; //here's your data!
    flexLoader.loadBytes(imageBytes); //useless here, just to show you it's possible
}
Exort
  • 1,075
  • 5
  • 13
  • Thanks for your answer! Unfortunately, I load ByteArray from cache and that is the issue. I'm trying completely not to load data from server, so `FlexLoader` with its `loadBytes()` is neccessary here. – moropus Sep 07 '11 at 12:14
  • Nope, you can load from cache anyway. The path to a file on a disk is also considered an URL, so you can use the URLLoader to load from there too. In fact, that's exactly what I use to cache my content. I build upon some code from someone else so I'm not using the SharedObject but it should work anyway. – Exort Sep 07 '11 at 12:47
  • So how can I save a file to directory in Flash (without AIR)? I think that's impossible. And the only way to have some data cached is SharedObject. – moropus Sep 07 '11 at 12:53
  • I'm sure there's a way to work with the SharedObject here. Unfortunatly, I have never used it and can't look up into it. However, my guess is you can use an URLLoader to load your data the first time around when it's not cached. That way, you'll save the bytes as is (else, you save the movie clip object). If this isn't enough, then you'll have to find a way to know the content type there and use the loader for swf and something like BitmapData for pngs and jpgs. Hope that helps! – Exort Sep 07 '11 at 13:16
  • It seems, that there's no way to predict what bytes FlexLoader will provide. So I'm switching to URLLoader in case of loading files from server and FlexLoader in case of loading bytes from cache. – moropus Sep 10 '11 at 13:43
1

I wasn't using Shared object to store anything but textual data. BUT. Maybe you can find something useful here: Is it possible to store images in the SharedObject of Flash?

The pre last answer contains link to an example. It seems like the approach there a bit differs from yours. P.S. The link is broken, but thanks to Google, we have a saved copy ;)

Community
  • 1
  • 1
Antenka
  • 1,519
  • 2
  • 19
  • 29
  • Thanks, nice approach to save Bitmaps as ByteArray retrieved from getPixels function. Unfortunately, it's not suitable in my situation, because I need to store both movies and images - and don't even know, what kind of media I'm trying to load. – moropus Sep 09 '11 at 11:58
  • What if, e.g. to have an util class, which would determine the resource type and depending on that, write it in a special way? Also you would be able to write there a Resource Type to restore it accordingly. If you ever need to extend the resource list - you would just add a specific load (instead of trying to guess, what type of problem you would have with a common loading approach and a new resource). Just a thought in a loud :) – Antenka Sep 09 '11 at 12:11
  • Sad truth, it's not reccomended to store something composite into SharedObject, as sometimes objects are not properly retrieved: e.g. instead of retrieving stored one the new instance of specific class is created (without a word, error, null reference or exception). Flash always makes developers to be on the alert :( – moropus Sep 09 '11 at 12:28
  • Well, it wasn't that much fun, if we had no Flex :P Can you say, in what type of application is this planned to be used? Is it a web site or a component on a site .. or a desktop application .. cause I'm already started to think of caching into a file system (there's nothing that's motivating me more to use custom solutions than this :) ) – Antenka Sep 09 '11 at 13:00
  • That's browser on-line flash game we're working on. Since it is browser game, we can't use AIR and cache directly into file system. – moropus Sep 09 '11 at 13:14
  • Uhu .. I see. What about custom cache in your game (Sort of hash table)? Usually we choose the speed over memory usage (or vice versa). I think, now we have a new problem: memory over unpredictability *giggle* – Antenka Sep 09 '11 at 15:36