Fragment
を設定してListView
を設定し、Handler
を作成してListview
を定期的に更新します。ただし、Handler
が破壊された後もFragment
はまだ実行されているようです。
以下はコードです。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//boilerplate code
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
assignAdapter();
handler.postDelayed(this, 15000);
}
});
return v;
}
ListView
の破棄後にFragment
を更新すると、アプリがクラッシュします。 Handler
が破壊されたときにFragment
を停止するにはどうすればよいですか?また、アプリを一時停止するとHandler
にもどのような影響があるかについても知りたいです。
このようなハンドラーを実装する必要があります
private Handler myHandler;
private Runnable myRunnable = new Runnable() {
@Override
public void run() {
//Do Something
}
};
@Override
public void onDestroy () {
mHandler.removeCallbacks(myRunnable);
super.onDestroy ();
}
ハンドラへの参照とランナブルへの参照をフラグメントに格納する必要があり、フラグメントが破棄されたら、ランナブルに渡されるハンドラからコールバックを削除する必要があります。
private Handler mHandler;
private Runnable mRunnable;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//boilerplate code
mRunnable = new Runnable() {
@Override
public void run() {
assignAdapter();
handler.postDelayed(this, 15000);
}
};
mHandler = new Handler(mRunnable);
mHandler.post();
return v;
}
@Override
public void onDestroy() {
mHandler.removeCallbacks(mRunnable);
super.onDestroy();
}
フラグメントにWeakReference
を使用してハンドラーを停止する別の方法:
_static final class UpdateUIRunnable implements Runnable {
final WeakReference<RouteGuideFragment> weakRefToParent;
final Handler handler;
public UpdateUIRunnable(RouteGuideFragment fragment, Handler handler) {
weakRefToParent = new WeakReference<RouteGuideFragment>(fragment);
this.handler = handler;
}
public void scheduleNextRun() {
handler.postDelayed(this, INTERVAL_TO_REDRAW_UI);
}
@Override
public void run() {
RouteGuideFragment fragment = weakRefToParent.get();
if (fragment == null || fragment.hasBeenDestroyed()) {
Log.d("UIUpdateRunnable", "Killing updater -> fragment has been destroyed.");
return;
}
if (fragment.adapter != null) {
try {
fragment.adapter.forceUpdate();
} finally {
// schedule again
this.scheduleNextRun();
}
}
}
}
_
ここで、fragment.hasBeenDestroyed()
は単にフラグメントのmDestroyed
プロパティのゲッターです。
_@Override
public void onDestroy() {
super.onDestroy();
mDestroyed = true;
}
_
誰かが同様の別の質問を投稿しましたが、問題はChildFragmentManager
のバグが原因です。基本的に、ChildFragmentManager
がActivity
から切り離されると、内部状態が壊れます。 元の答えはこちら を見てください
Rxjavaを使用してください。
subscription = Observable.timer(1000, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> whatToDo());
private void whatToDo() {
System.out.println("Called after 1 second");
}
次に、ondestroy()メソッド呼び出しで
RxUtils.unsubscribe(subscription);