1

少し問題があります。

環境

環境: Flex 3 (実際には Flex 4 SDK に更新されていますが、まだsparkの代わりにmxを使用しています)

IDE: フラッシュ ビルダー 4.6。

ブラウザ: Firefox 14.0.1

Flash Player のバージョン: FP 11 Debugger - 11.2.202.235

ステート構文: Flex 3 スタイルの構文。

アプリケーション

私はアプリケーションを持っています。

このアプリケーションにはいくつかの状態があります。

状態の 1 つには、次のwrapperComponent3 つの異なる状態を持つ " " があります。基本状態 ("")、" firstState"、および " secondState" です。

少し単純化すると、これらの各状態に含まれるもののほとんどは、次のように異なるカスタム コンポーネントです。

  • " wrapperComponent" -> " base comp."
  • " firstState" -> " first comp."
  • " secondState" と " second comp."

次の画像は、状況をより明確に示しています。

アプリケーションのコンポーネントと状態の階層

次に、ユーザーが " " を使用している場合、wrapperComponent最初に " " に到達しfirstState、次に " " を使用し、その後、次の図に示すようにbase state" " に移動します。secondState

ラッパー コンポーネントの状態の流れ

それで、問題は...

したがって、問題は、ユーザーがフローの 3 番目のステップに到達したとき、つまり、「secondState」の「 wrapperComponent」に到達したときに、「second comp.」が表示される場合と表示されない場合があることです。

これまでの調査結果は...

Adobe フォーラムでのディスカッション: http://forums.adobe.com/message/4621058 3

これに約 2 週間苦労した後、何らかの形で ActionScript のイベントの内部フローが停止しているという半ば結論に達しました。

これは、「second comp.」というカスタム コンポーネントが画面に表示されない場合、次のことを意味します。

  • base state" " から " " への遷移secondStateが停止/一時停止/停止し、
  • " " の一部のイベントのみsecond comp.がディスパッチされます (" preinitialize"、" initialize"、" add"、" added" がディスパッチされます) が、他のいくつかのイベントはディスパッチされません: " addedToStage" および " creationComplete" はディスパッチされません。
  • " "と" activeEffects" の両方の変数 " " には、再生されない効果 ("RemoveChildActionInstance" や "AddChildActionInstance" など) が含まれ、base comp.second comp.
  • updateCompletePendingFlagこれらの同じコンポーネントの値の変数 " " は " true" で、更新が完了していないことを意味します。

醜いハック_

この回避策で、問題を回避する本当に恐ろしい方法を見つけました。

  • baseState状態が " "から " " に変わる必要があるときにカウントを開始する 500ms タイマーを設定しましたsecondState(つまり、上の画像のステップ 2 からステップ 3 へ)。
  • このタイマーがオフになると、コンポーネント (つまり " base comp." または " second comp.") に保留中の効果があるかどうか、またはそれらの " updateCompletePendingFlag== true" かどうかを確認します。
  • チェックが true の場合、validateDisplayList()その特定のコンポーネントでメソッドの呼び出しを強制します。

コードは次のようになります。

...
if ( toState == STATE_SECOND ) {
var theTimer    : Timer = new Timer(500,1);
theTimer.stop();
theTimer.addEventListener(
TimerEvent.TIMER_COMPLETE, 
theTimer_complete_Hdl, 
false, 0, true
);
theTimer.start();

currentState = STATE_SECOND ;
}
...

そして、タイマーは次の関数を呼び出します。

private function theTimer_complete_Hdl(event:TimerEvent):void
{
if (secondComp.updateCompletePendingFlag)
{

secondComp.invalidateDisplayList();
secondComp.validateDisplayList();
secondComp.validateNow();
this.invalidateDisplayList();
this.validateDisplayList();


}
...
} 

問題...

これは実に汚い、洗練されていないコードです。さらに、画面を更新するのに 1 秒以上かかり、動きが速くないため、ユーザー エクスペリエンスが低下します。

私の推測では、何らかの形でパフォーマンスに悪影響を及ぼしていると思います。

**何が起こっているのか、または FlashPlayer に効果を強制終了して updateDisplayList を強制するのではなく、強制的に再生を継続させるためのより良い方法に関するアイデアはありますか?**

君たちありがとう!!!:-)

4

1 に答える 1

0

これはFlashPlayerのバグだと真剣に考えました。

明らかに、最も可能性の高い答えは、実際にそうであったように、それは私の間違いだったということでした。

難しいことではなく、プロジェクトが複雑で、問題のあるクラスとは直接関係のないクラスに問題があったため、これに多くの時間を費やしました。

原点を特定した後、これはかなり簡単な修正でした。

問題の原因は何ですか?

myCustomComponentと一緒に、前の状態の別のカスタムクラスを使用していました(つまり、 " base comp."の""内base state)。

これによりcustomClass、flexmxLabelクラスが拡張されました。commitProperties()オーバーライドされたメソッドでは、フラグがfalseに設定されず、再度呼び出されましinvalidateProperties()た。もちろん、これは間違いであり、このクラスで無限ループを引き起こしていました( " base comp."コンポーネントに5つのインスタンスがあります)。

これにより、アプリケーションの実行が妨げられることはありませんでした。それはそれを止めませんでした。myCustomComponentただし、トランジションで定義されたエフェクトの実行とインスタンスの作成の終了が妨げられました。

base comp.その小さな間違いがあった""の擬似コードは次のようなものでした:

override protected function commitProperties():void
{
    super.commitProperties();
    if (somethingChanged)
    {
        //1: I wasn't setting somethingChanged=false
        
        //2: I needed to call invalidateProperties() again, like this:
        invalidateProperties();     
    }
}

正しいバージョンは次のとおりです。

override protected function commitProperties():void
{
    super.commitProperties();
    if (somethingChanged)
    {
        //1: I added this line:
        somethingChanged=false;

        //2: I still need to call invalidateProperties() again, like this:
        invalidateProperties();     
    }
}

またはさらに良い:

override protected function commitProperties():void
{
    if (somethingChanged)
    {
        //1: I added this line:
        somethingChanged=false;

        //2: Instead of invalidating the properties, doing some  
        //  processing and calling super.commitProperties()
        ...; //  (some processing)
    }
    super.commitProperties();       
}
于 2012-08-28T21:06:06.257 に答える