外部からロードされた SWF ファイルを Adob​​e Flex の SWFLoader コンポーネントからアンロードするにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/117900

質問

外部 SWF ファイルをロードし、Adobe Flex / Air アプリケーション内で再生するアプリケーションがあります。 SWFLoader フレックスコンポーネント. 。ボタンクリックイベントからそれらをアンロードする方法を見つけようとしています。私はGoogleで広範囲にわたって検索しましたが、ハッキングなしでそれを行うことができた人は誰もいなかったようです。人々が使用しているコードの組み合わせは次のとおりです。

swfLoader.source = ""; // Removes the external link to the SWF.
swfLoader.load(null); // Forces the loader to try to load nothing.
// Note: At this point sound from the SWF is still playing, and
// seems to still be playing in memory.
flash.media.SoundMixer.stopAll();
// Stops the sound. This works on my development machine, but not 
// on the client's.

この方法で SWF を閉じる (非表示にする) と、最終的にプログラムがクラッシュします。

何か案は?さまざまなフォーラムで、同じ問題を抱えている人々の投稿がたくさん見つかりました。ここで間違った/不完全な回答が 1 つあると思います。その場合、私の投稿はいつものように空に沈んでしまいますが、いずれにせよ、よろしくお願いします。

編集1:実際の SWF ムービーは編集できません。クライアントが作成したものです。Flex を通じて開いた SWF を閉じることができない場合、それは Flex アーキテクチャに問題があるのではないでしょうか?SWF を Web ブラウザに送信する唯一のオプションはありますか?

役に立ちましたか?

解決

...それは Flex アーキテクチャの問題ではないでしょうか?

はい、それは Flash 全般にも影響します。を活用できるようになるまでは、 Loader.unloadAndStop() FP10 (AIR 1.5) のメソッドでは、外部からロードされたコンテンツがメモリと CPU リソースを消費し続けないことを保証できません。 Loader.unload() 方法。(正直に言うと、それでもリソースの解放が保証されるかどうかは 100% わかりませんが、おそらく私は悲観的です。)

次善の策は、読み込むコンテンツの作成者が一連のガイドラインに従うよう主張することです。 dispose() アプリが呼び出す前に、できるだけ多くのリソースを解放するように要求できるメソッド。 unload() それ。これが不可能な場合、外部 SWF をロードするたびにアプリケーションのメモリと CPU 使用率がほぼ確実に肥大化します。ごめん。

それで気分が少しでも良くなるなら、あなたは一人ではありません。;)

他のヒント

不適切に作成された SWF によってアプリケーションがシンクされる可能性があるのは問題ですが、他の人が述べているように、これに関する問題の多くは Flash Player 10 で修正される予定です。ただし、プラットフォームに関係なく、サードパーティのコードをロードすると問題が発生するリスクが常にあり、バグ、メモリ リーク、または完全に悪意のあるコードが含まれる可能性が常にあります。コンテンツをサンドボックスにロードできない限り (少なくとも現時点では Flash にはロードできません)、不正なものをロードするとアプリが沈んでしまいます。それは非常に簡単です。

残念ながら、読み込まれたコンテンツの品質を保証できない限り、自分のアプリケーションの品質も保証できません。Flash 開発者は、リークするものやアンロードできないものを作成することで有名です。これは、Flash を使用すると、特にタイムライン上に存在するものの場合、間違ったことが簡単に実行できるためです。直接制御できない Flash コンテンツをロードすることは非常に危険です。

最良の解決策は

swfLoader.autoLoad = false;
swfLoader.unloadAndStop();
swfLoader.autoLoad = true;

このようにして、プレーヤーを停止し、コンテンツをメモリからアンロードして、サウンドが再生されたままになるのを防ぎます。乾杯

問題はロードされた SWF にあり、それ自体の後でオーディオをクリーンアップしないだけです。次のようにムービークリップにアンロード イベントをアタッチしてみてください。

MovieClip(event.target.content).loaderInfo.addEventListener(Event.UNLOAD, unloadMovieClipHandler);
private function unloadMovieClipHandler(event:Event) : void
{
  SoundMixer.stopAll();                           
} 

私は通常、SWFLoader から離れて、mx.modules パッケージ内のクラスを使用します。

Flex には、この種の動作を可能にするモジュール システムがあります。ここで確認できます: http://livedocs.adobe.com/flex/3/html/help.html?content=modular_3.html 。一般に、swf コンポーネントを動的にロードおよびアンロードすることは、特にそれらのモジュールがアプリケーション内のグローバル状態 (スタイルなど) を変更する場合には注意が必要です。ただし、モジュールのインターフェイスを作成し、ロード/アンロードする各クラスがそのインターフェイスを実装するだけでなく、フレックス モジュール クラスを拡張すると、それらをクリーンにロードおよびアンロードできます。

次のことを試してください。

try {
   new LocalConnection().connect('foo');
   new LocalConnection().connect('foo');
} catch (e:*) {}

これにより、ガベージ コレクション ルーチンが強制的に実行されます。SWF がまだ接続されている場合は、オーディオなどの何らかの接続が失われています。

GC を強制する方法はいくつかありますが、どれも CPU に負荷がかかるため最悪の方法ですが、良いニュースとして、Flash Player 10 では正式な方法が登場します。

unloadAndStop

リンク: http://www.gskinner.com/blog/archives/2008/07/unloadandstop_i.html

それまでは、上で示したようなハックを使って強制的に解決する必要があると思います。

すべてのコードを示していないため、Loader クラスの unload メソッドを使用していないと仮定します。また、ロードメソッドがURLRequestオブジェクトを期待しているため、swfLoader.load(null)は間違っているように思えます。最後にクリーンアップしたい場合は、null ロードを呼び出す代わりに、オブジェクトの値を null に設定します。まだ音声が聞こえるということは、データがアンロードされていないか、アンロードされたコンテンツ内に音声ファイルが存在していないことを示しています。これを見ていきましょう。

以下の例


var loader:Loader = new Loader();
var request:URLRequest = new URLRequest('test.swf');
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onSwfLoad, false, 0, true);

function onswfload(e:event):void {addchild(loader);loader.contentLoaderInfo.addEventListener(Event.UNLOAD, onLoaderUnload, false, 0, true);

loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onSwfLoad, false);} function onloaderunload(e:event):void {trace( 'ローダーは正常にアンロードされました。');} //ボタン名がbutton_mc button_mc.addeventlistener(mouseevent.mouse_down、onbuttondown、false、0、true)であると仮定して、ボタンをクリックしてこれを削除します。

function onButtonDown(e:MouseEvent):void { loader.unload(); loader.contentLoaderInfo.removeEventListener(Event.UNLOAD, onLoaderUnload); //When you want to remove things completely from memory you simply set their value to null. loader = null; button_mc.removeEventListener(MouseEvent.MOUSE_DOWN, onButtonDown); }

これがお役に立てば幸いです。冗長でしたら申し訳ありませんが、コードを見ないと、これにどのようにアプローチしたかを正確に知る方法はありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top