Handler+Runnableによるサイクルタイミングの実現
1813 ワード
今日、appに小さな機能を追加しました.Fragmentでは、サーバおよびローカル・データベースへの情報の定期的な格納を実現します.前後して3つの案を用いてやっと実現したので,波乱が絶えないと言える.
最初の案はTimer+TimerTask案で、この2つはあまり言わないので、皆さんもどのように使うかよく知っていると思います.実際にも確かにそうです.簡単に機能を実現しました.しかし、テストの時、現在のインタフェースから任意の他のインタフェースにジャンプして戻ったとき、Appは意外にCrashになったことがわかりました.異常を報告:Timerはもうcancelしました.実際にonDestroy()メソッドでTimerとTimerTaskのcancelメソッドを呼び出さなくても、同じようにクラッシュします.仕方なく、時間がきついので、原因を探す暇がありません.早速シナリオを変えて、RxJava 2のTimer機能ですが、今回はもっと悲劇的で、このFragmentでは、元の作者がjavaを引用しました.util.Observableとjava.util.Observerオブジェクト.RxJava 2の2つのオブジェクトを呼び出すことはできません.本当に苦しいですね.その後、スキームを変更します.Handler+Runnableは、サイクルタイミングを実現します.今度はやっと吉報が届いた.具体的には、次のようになります.
ActivityまたはFragmentのonResume()メソッドで
次のコードを必要な場所で実行し、デッドサイクルの継続をキャンセルできます.
このようにしてTimer+TimerTaskの機能を実現し,より簡単である.
探索を経て、Timer+TimerTask方案が崩壊した解決方案:1、崩壊原因:
2、解決方案:動的にTimerTaskオブジェクトを作成する:
timerが空かどうかを判断してからTimerTaskを動的に作成すると、cancel or scheduledの異常は報告されません.
最初の案はTimer+TimerTask案で、この2つはあまり言わないので、皆さんもどのように使うかよく知っていると思います.実際にも確かにそうです.簡単に機能を実現しました.しかし、テストの時、現在のインタフェースから任意の他のインタフェースにジャンプして戻ったとき、Appは意外にCrashになったことがわかりました.異常を報告:Timerはもうcancelしました.実際にonDestroy()メソッドでTimerとTimerTaskのcancelメソッドを呼び出さなくても、同じようにクラッシュします.仕方なく、時間がきついので、原因を探す暇がありません.早速シナリオを変えて、RxJava 2のTimer機能ですが、今回はもっと悲劇的で、このFragmentでは、元の作者がjavaを引用しました.util.Observableとjava.util.Observerオブジェクト.RxJava 2の2つのオブジェクトを呼び出すことはできません.本当に苦しいですね.その後、スキームを変更します.Handler+Runnableは、サイクルタイミングを実現します.今度はやっと吉報が届いた.具体的には、次のようになります.
ActivityまたはFragmentのonResume()メソッドで
@Override
public void onResume() {
super.onResume();
// 2
mHandler.postDelayed(runnable, 10 * 1000);
}
Runnable runnable = new Runnable() {
@Override
public void run() {
//TODO:
// :onResume mHandler.postDelayed , , , ( )
mHandler.postDelayed(runnable, 10 * 1000);
}
};
次のコードを必要な場所で実行し、デッドサイクルの継続をキャンセルできます.
mHandler.removeCallbacks(runnable);
このようにしてTimer+TimerTaskの機能を実現し,より簡単である.
探索を経て、Timer+TimerTask方案が崩壊した解決方案:1、崩壊原因:
Timer or TimerTask is cancel or scheduled
2、解決方案:動的にTimerTaskオブジェクトを作成する:
Timer timer = null;
@Override
public void onResume() {
super.onResume();
// 2
if ( null == timer){
timer = new Timer();
}
timer.schedule(new TimerTask() {
@Override
public void run() {
Log.i("mHandler", "run: mHandler====timerTask");
//TODO:
}
}, 5 * 1000, 5 * 1000);
}
timerが空かどうかを判断してからTimerTaskを動的に作成すると、cancel or scheduledの異常は報告されません.