Adobe
製品
Acrobat
Creative Cloud
Creative Suite
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
その他の製品一覧
ソリューション
デジタルマーケティング
デジタルメディア
教育
金融機関
Web Experience Management
その他のソリューション
ラーニング サポート ダウンロード 会社情報
ご購入
アドビストア 安心のサポート& サービス
アカデミックストア 学生、教職員、個人向け
アドビライセンスストア 中小企業向け
ボリュームライセンスについて 企業、教育機関、官公庁向け
販売パートナー
キャンペーン情報
検索
 
情報 サインイン
ようこそ、 さん カート 注文状況 マイアカウント
マイアカウント
注文状況
アカウント情報の変更
コミュニケーションの設定を変更
サインアウト
サインインの目的 お客様のアカウントや体験版ダウンロード、製品の拡張機能、コミュニティエリアへのアクセスなどを管理するため
Adobe
製品 セクション ご購入   検索  
ソリューション 会社情報
サポート ラーニング
サインイン サインアウト 注文状況 マイアカウント
先行予約の提供開始予定日Date. 商品が発送されるまで、クレジットカードには課金されません。提供開始の予定日は変更される場合があります。 先行予約の提供開始予定日Date. ダウンロードの準備が整うまで、クレジットカードには課金されません。提供開始の予定日は変更される場合があります。
個数:
ご購入には学生・教職員個人版の購入資格の確認が必要です。
小計
カートの中身を見る
Adobe Developer Connection / Flexデベロッパーセンター /

ActionScript Thread Library 1.0 (そうめん) で非同期処理をスマートに

著者 新藤愛大氏

新藤愛大氏
  • Spark project

Content

  • ActionScript Thread Library 1.0 (そうめん) とは
  • データ読み込みの例
  • もう少し複雑な読み込みの例
  • エラー処理の例
  • アニメーションの例
  • 処理のキャンセルの例
  • おわりに

作成日

28 September 2008

ページ ツール

Facebookでシェア
Twitterでツイート
LinkedInでシェア
ブックマーク
印刷

タグ

必要条件

ユーザーレベル

すべて

必要な製品

  • Flash Professional CS3 (Download trial)

ActionScript Thread Library 1.0 (そうめん) とは

はじめにこの処理をして、次にこの処理をして...、という処理の流れを「スレッド (Thread)」と呼びます。英単語の「Thread」には「糸」「縫い糸」「筋道」「脈絡」といった意味があります。

ActionScript 3.0 (FlashPlayer 9) は、処理の流れがひとつしかない「シングルスレッド」で、かつイベントを介して処理を進める「イベント駆動」を採用しているため、データのロード完了を待つ、ユーザーがマウスをクリックするのを待つ、といった非同期処理が入るととたんにコードが複雑になる傾向があります。 そこで登場するのが ActionScript Thread Library 1.0 (そうめん) です。

ActionScript Thread Library は、タスクシステムと Java のスレッドモデルをベースとした「疑似スレッド」を実現するライブラリで、複雑で冗長になりがちな、イベント処理や非同期処理、リアルタイム処理を、分かりやすくスマートに記述することを可能にします。

データ読み込みの例

最近の Flash や Flex では、外部データのやり取りをしない方が少ないと思います。特に、XML や、外部 SWF の読み込みは、必ずと言っていいほど行われます。

たとえば、複数の XML を順番に読み込んで、全ての読み込みが終わったら何か処理をする、という例を、ActionScript Thread Library を使って書くと、次のようになります。

import org.libspark.thread.Thread; import org.libspark.thread.threads.net.URLLoaderThread; import org.libspark.thread.utils.SerialExecutor; public class LoadXMLsThread extends Thread { private var _loaders:SerialExecutor; override protected function run():void { // みっつの XML を読み込む _loaders = new SerialExecutor(); _loaders.addThread(new URLLoaderThread(new URLRequest('a.xml')); _loaders.addThread(new URLLoaderThread(new URLRequest('b.xml')); _loaders.addThread(new URLLoaderThread(new URLRequest('c.xml')); _loaders.start(); _loaders.join(); next(loadComplete); } private function loadComplete():void { // 何か処理をする... ここでは XML の内容を出力 for (var i:uint = 0; i < _loaders.numThreads; ++i) { trace(URLLoaderThread(_loaders.getThreadAt(i)).loader.data); } } }

ここで、三つの新しいクラスが登場しています。

  • Thread
    全てのスレッドの元となる基底クラスです。この例のように、独自のスレッド (LoadXMLsThread) を作る場合も、このクラスを継承して、run メソッドをオーバーライドすることで処理を書きます。
  • URLLoaderThread
    URLLoader を用いてデータを読み込むスレッドです。コンストラクタで指定された URLRequest を用いてデータを読み込み、完了するとスレッドが終了します。
  • SerialExecutor
    複数のスレッドを、addThread メソッドで追加された順で、順番に実行するスレッドです。あるスレッドの実行が終了すると次のスレッドを実行し、全てのスレッドの実行が終了するとこのスレッドの実行が終了します。

Thread クラスの start メソッドを呼び出すと、スレッドの実行が開始されます。

_loaders.start();

ここでは、SerialExecutor の実行が開始され、addThread されている、「a.xml」と「b.xml」と「c.xml」を読みにいく URLoaderThread が、順番に実行されます。

Thread クラスの join メソッドを呼び出すと、呼び出した先のスレッドの終了を待機して、next メソッドで指定したメソッドを終了後に呼び出すようになります。

_loaders.join(); next(loadComplete);

そのため、SerialExecutor の実行が終了 (= 全ての URLLoaderThread の読み込みが終了) すると、loadComplete メソッドが呼び出され、取得した XML の内容が出力されます。

もう少し複雑な読み込みの例

実際の開発では、読み込みの処理は更に複雑になることがあります。例えば、まず XML を読んで、その内容を元に、画像ファイルを読み込んで表示する、といった処理です。

これを ActionScript Thread Library を使って書いてみると次のようになります。

import org.libspark.thread.Thread; import org.libspark.thread.threads.net.URLLoaderThread; import org.libspark.thread.threads.display.LoaderThread; import org.libspark.thread.utils.SerialExecutor; public class LoadXMLandImageThread extends Thread { private var _loader:URLLoaderThread; private var _loaders:SerialExecutor; override protected function run():void { // XML を読み込む _loader = new URLLoaderThread('images.xml'); _loader.start(); _loader.join(); next(loadXMLComplete); } private function loadXMLComplete():void { // 読み込んだ XML から更に画像を読み込むスレッドを作成して実行する _loaders = new SerialExecutor(); var xml:XML = XML(_loader.loader.data); for each (var item:XML in xml.item) { _loaders.addThread(new LoaderThread(new URLRequest(String(item)))); } _loaders.start(); _loaders.join(); next(loadImagesComplete); } private funciton loadImagesComplete():void { // 表示処理など... } }

ここで、次のクラスが新しく登場しています。

  • LoaderThread
    Loader を用いて画像などを読み込むスレッドです。コンストラクタで指定された URLRequest を用いて画像などを読み込み、完了するとスレッドが終了します。

はじめに、URLLoaderThread を用いて「image.xml」を読み込んでいます。読み込みが完了すると、next メソッドによって指定された loadXMLComplete メソッドが呼び出されます。

loadXMLComplete メソッドでは、読み込んだ XML の item 要素を取得し、そこに書かれているファイル名の画像を読み込む LoaderThread を作成して、SerialExecutor に追加しています。

たとえば、images.xml が次のような内容であった場合、

<items> <item>a.jpg</item> <item>b.jpg</item> <item>c.jpg</item> </items>

「a.jpg」「b.jpg」「c.jpg」がそれぞれ LoaderThread によって読み込まれます。読み込みが完了すると、next メソッドによって指定された loadImagesComplete メソッドが呼び出されます。

このように、ActionScript Thread Library では、Thread の start メソッド、join メソッド、next メソッドなどを組み合わせて、処理を柔軟に記述することが出来ます。

エラー処理の例

エラーが発生した場合に、それをそのまま放っておくのは不親切です。エラーメッセージを表示する、リトライするなど、何か処理を行いたい場合がほとんどだと思います。

URLLoaderThread や、LoaderThread は、エラー (内部的にはエラーイベント) が発生した場合に、それを例外としてスローします。スローされた例外は、親スレッド (そのスレッドを開始したスレッド) に伝播していくようになっています。そのようにして伝播してきた例外は、error メソッドで捕捉することができます。

import org.libspark.thread.Thread; import org.libspark.thread.threads.net.URLLoaderThread; import flash.errors.IOError; public class LoadXMLandImageThread extends Thread { private var _loader:URLLoaderThread; override protected function run():void { _loader = new URLLoaderThread('data.xml'); _loader.start(); _loader.join(); next(loadComplete); error(IOError, loadError); error(SecurityError, loadError); } private function loadComplete():void { trace(_loader.loader.data); } private funciton loadError(e:Error, t:Thread):void { trace('読み込みエラーが発生しました'); next(null); } }

error メソッドでは、第一引数ひ捕捉したい例外の種類、第二引数に例外発生時に呼び出すメソッドを指定します。この例では、IOError (内部的には IOError イベント) かSecurityError (内部的には SecurityError イベント) が発生した際に、loadError メソッドが呼び出されます。エラーが発生しなかった場合、loadComplete が呼び出されます。

例外発生時に呼び出されるメソッドは、第一引数に発生した例外、第二引数に例外が発生したスレッドを採るようにします。このメソッドが何事も無く終了すると、例外発生前に実行していたメソッドに復帰します。ここでは、next メソッドに null を指定することで、なにもせずスレッドが終了するようにしています。

ActionScript Thread Library では、このように、try-catch ライクに例外処理をすることが出来ます。

アニメーションの例

これまでデータの読み込みを例に見てきましたが、もちろん、アニメーションにも使用することが出来ます。
次の例では、1秒ごとに、ランダムな位置に Sprite をアニメーションさせながら移動させます。

import org.libspark.thread.Thread; import org.libspark.thread.threads.tweener.TweenerThread; import flash.display.Sprite; public class AnimationThread extends Thread { public function AnimationThread(sprite:Sprite) { _sprite = sprite; } private var _sprite:Sprite; override protected function run():void { var tweener:TweenerThread = new TweenerThread(_sprite, { time: 0.5, x: Math.random() * _sprite.stage.stageWidth, y: Math.random() * _sprite.stage.stageHeight, transition: 'easeOutCubic' }); tweener.start(); tweener.join(); next(tweenComplete); } private function tweenComplete():void { sleep(1000); next(run); } }

ここで、次のクラスが新しく登場しています。

  • TweenerThread
    Tweener を用いてアニメーションを行うスレッドです。コンストラクタで指定されたターゲットとパラメータを用いて Tweener でアニメーションを行い、完了するとスレッドが終了します。

スレッドの実行が開始されると、コンストラクタで指定された Sprite に対して、TweenerThread を用いて、ランダムな座標に 0.5 秒かけて移動するアニメーションを実行します。
アニメーションが終了すると、next メソッドで指定された tweenComplete メソッドが呼び出されます。

tweenComplete メソッドでは、sleep メソッドを呼び出して、1000 ミリ秒後 (1 秒後) に、next メソッドで指定した run メソッドが実行されるようにしています。
run メソッドが実行されるということは、再び TweenerThread が実行され、アニメーションをし、また 1 秒待ち、という風に、処理がループするようになります。

処理のキャンセルの例

既に行われている動作に割り込んで、別の動作を行う、すなわちキャンセル処理を行いたい、というのも、実際の開発ではよくあることです。
ActionScript Thread Library では、スレッドに対するキャンセル機能を実現する、汎用的な割り込み機構を提供しています。

次の例では、さきほどのランダムな座標にアニメーションするスレッドに対して、キャンセル (割り込み) が要求された場合は、Sprite をフェードアウトして消すという処理を行います。

import org.libspark.thread.Thread; import org.libspark.thread.threads.tweener.TweenerThread; import flash.display.Sprite; public class AnimationThread extends Thread { public function AnimationThread(sprite:Sprite) { _sprite = sprite; } private var _sprite:Sprite; override protected function run():void { var tweener:TweenerThread = new TweenerThread(_sprite, { time: 0.5, x: Math.random() * _sprite.stage.stageWidth, y: Math.random() * _sprite.stage.stageHeight, transition: 'easeOutCubic' }); tweener.start(); tweener.join(); next(tweenComplete); // 割り込まれた場合 interrupted(tweenInterrupted); } private function tweenComplete():void { sleep(1000); next(run); // 割り込まれた場合 interrupted(tweenInterrupted); } private function tweenInterrupted():void { var tweener:TweenerThread = new TweenerThread(_sprite, { time: 0.5, alpha: 0 }); tweener.start(); tweener.join(); next(tweenInterruptedComplete); } private function tweenInterruptedComplete():void { _sprite.parent.removeChild(_sprite); } }

interrupted メソッドを用いると、割り込み要求がされた場合に実行されるメソッドを指定出来ます。
ここでは、tweenInterrupted メソッドを指定しているため、新たに TweenerThread によってアルファが 0 になるアニメーションが実行され、そのあとで、next メソッドで指定されている tweenInterruptedComplete メソッドが呼び出され、表示オブジェクトツリーから削除されます。

実際に割り込み要求を出すには、実行中のこの AnimationThread のインスタンスに対して、interrupt メソッドを呼び出します。

animationThread.interrupt();

こうすると、割り込みフラグが設定され、通常の動作から、割り込み動作に移行します。

おわりに

ActionScript Thread Library 1.0 (そうめん) を使ううえでの最大のメリットは、非同期処理を含む、全てのコントローラ的な処理が、このスレッドのスタイルで統一して記述できるところにあります。そのおかげで、コードが読み易くすっきりし、開発スピードも上がりますし、処理の順番の入れ替え等が簡単なため、開発途中での仕様変更にも強くなります。

開発者の僕自身、既にいくつかの仕事で使っており、ActionScript Thread Library なしには生きていけない体になっています。
仕事レベルの複雑な処理ほど威力を発揮するので、是非皆さんも使ってみて下さい。

詳細や、ダウンロード、サンプルや制作事例等は以下のページで見ることが出来ます。

  • Thread - Spark project

ドキュメントは以下にありますので、是非一度目を通してみて下さい。

  • ActionScript Thread Library 1.0 (そうめん) ドキュメント

製品

  • Acrobat
  • Creative Cloud
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • モバイルアプリ
  • Photoshop
  • Touch Apps

ソリューション

  • デジタルマーケティング
  • コンテンツオーサリング
  • Web Experience Management

業種別ソリューション

  • 教育
  • 金融機関

サポート

  • ヘルプ&サポート
  • 注文と返品
  • ダウンロードに関するヘルプ
  • ユーザー登録に関するヘルプ

ラーニング

  • ADC: Adobe Developer Center
  • Adobe TV
  • Design Magazine
  • Photoshop Magazine
  • Focus In

ご購入方法

  • アドビストア
  • アカデミックストア
  • アドビライセンスストア
  • ボリュームライセンスについて
  • 販売パートナー
  • キャンペーン情報

ダウンロード

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

会社情報

  • プレスルーム
  • パートナープログラム
  • 企業の社会的責任(英語)
  • 採用情報
  • 投資家の皆様へ(英語)
  • イベント&セミナー
  • Legal(英語)
  • セキュリティ
  • お問い合わせ
国・地域および言語の選択 日本(変更)
国・地域および言語の選択 閉じる

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

利用条件 | プライバシーポリシーとCookie (更新)

Reviewed by TRUSTe: site privacy statement