2016-12-22 5 views
0

ライフサイクルについて質問があります。活動が壊れるのを待つ

私には2つのアクティビティがあります。 (ちょうどそれをAとBと呼ぶ)。 AがMainActivityの場合アクティビティBを呼び出すbuttonがあります。 アクティビティBでは、戻るボタンを押すとfinish()が呼び出されます。

私がfinish()と呼ぶと大丈夫ですが、しばらく待ってからもう一度Bを呼んでも大丈夫です。 しかし、私はfinish()を呼び出すと、すぐにより再びBを呼び出したときに 前のBのonDestroy()が呼び出され後に新しいBのonCreate()onResume()

MediaPlayeronResume()onPause() ...どこでも対応していますので、私にとって問題です。

​​

私が戻ってBをもう一度早く呼び出すと、前の音が止まって止まります。 別のクラスがmediaPlayerを制御しているので、のstaticフィールドは削除できません。

私はonDestroy(を待ってこれを処理できると思います)。 Bが完全に破壊されるまでMainActivity(A)を待機させる方法はありますか?

+1

は、あなただけの仕上げの前に()手動でのMediaPlayerを解放できませんか?あなたがすでにnullをチェックしているので、これは問題ではありません。 – Leandro

答えて

3

あなたがに作成され、を破壊され、どの活動を知ることができ、アプリケーションのクラスのためのActivityLifeCycleCallBack Listnerがあります。

これは、あなたが簡単にApplication.ActivityLifecycleCallbacks

0

onDestroy()がコールされた時点では制御できません。そのため待機しません。

あなたのケースでは、onPause()mediaPlayer.release()を呼び出す必要がありますどちらかとonResume()でそれを作成するか、単に独立してあなたがカウントされ、ロックを導入することができます活動

1

のライフサイクルの既存のそれを残す、のような:

class X extends Activity { 

    private static int runningTimes = 0; 

    private synchronized void lockPlayer() { 
     ++runningTimes; 
    } 

    private synchronized boolean releasePlayer() { 
     return (0 == --runningTimes); 
    } 

    @Override 
    onCreate(...) { 
     super.onCreate(...); 
     lockPlayer(); 
    } 

    @Override 
    protected void onDestroy(){ 
     if(releasePlayer() && mediaPlayer != null) { 
      mediaPlayer.release(); 
      mediaPlayer = null; 
     } 
     super.onDestroy(); 
    } 

} 

両方のアクティビティがonCreate/onDestroyの同じUIスレッドで実行されると思いますか?その提案された同期化は、本当に並列実行を生き残るために十分に頑強ではないからです。それらが同じUIスレッド上にある場合は、実際には​​を++/- メソッドから削除することができます。これは、onCreate/onDestroyの順序だけが問題であり、同時に実行されるのではないからです。

super.on<EndingEvent>()には、オーバーライドされたハンドラの最後ではなく、最初から呼び出すようにすることをお勧めします(実際にはこのバグは発生しませんが、ソース "手続き的に ")。


警告:あなたは、単に今までプレイヤーを解放しないであろうと、あなたが正しくのonCreate/onDestroyペアに届かない場合には、カウンタは、おそらくそれがはるかに害をしないだろう...同期されていない値になることがあります次に。しかし、私は、OS全体がすでにクラッシュの危機に瀕している状況を除いて、onCreate/onDestroyを確実に呼び出すAndroid OSの一般的な良い経験を持っています。

+0

あなたの答えをありがとう。また役に立ちました。 –

0

さて、あなたの現在のロジックを実装するのに役立ちます、私はこれは仕事ができると思う:

class B extends Activity { 
    public static boolean destroyed = 1; 
    . 
    . 
    . 
    public void onCreate(Bundle args) { 
      destroyed = 0; 
      . 
      . 
      . 
    } 
    public void onDestroy() { 
      . 
      . 
      . 
      destroyed = 1; 
    } 
} 
class A extends Activity { 
    . 
    . 
    . 
    buttonB.setOnItemClickListener(new OnItemClickListener() { 
      public void onClick(View v) { 
       while (B.destroyed == 0); 
       Intent i = new Intent(); 
       . 
       . 
       . 
       startActivity(i, B.class); 
      } 

    }) 
} 

Bが破壊されるまで、「B.destroyed == 0」の部分が待っています新しい意図を開始します。

注:また、あなたが活動Bに呼び出すことができますAPI17から始まる()メソッドがisDestroyedだ、のようななめらか:https://developer.android.com/reference/android/app/Activity.html#isDestroyed()

+0

まあ..これは潜在的なANRを含んでいませんか? –

+0

ボタンはアクティビティAに配置され、Bは1秒未満で消滅します。これがどのようにANRを投げることができるのか分かりませんか? –

+0

を参照してください。ご回答有難うございます。 –

関連する問題