我有一个前台服务,每 5 分钟检查一次股票报价。该服务从启动它的父 FragmentActivity 传递一个 Messenger。
股票报价检查服务将 Message 传递回此 Handler,它是父 FragmentActivity 的内部非静态类:
private class YahooServiceHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case App.QUOTE_UPDATE_FINISHED:
Bundle bundle = msg.getData();
mTickerQuoteIds = bundle.getStringArray("ticker_quote_ids");
// I need this class to be an inner non-static class to do
// references to the other fragments this activity hosts.
QuoteListFragment quoteListFragment = (QuoteListFragment)mAdapter
.getRegisteredFragment(1);
quoteListFragment.mLoader.onContentChanged();
// This loops through some Ids returned in the Message to show
// dialogs for quotes that have passed their price limits
if (mTickerQuoteIds != null && mTickerQuoteIds.length > 0) {
for (int i = 0; i < mTickerQuoteIds.length; i++) {
String[] tickerQuoteId = mTickerQuoteIds[i].split("\\|");
FragmentManager fm = getSupportFragmentManager();
Bundle bundleArgs = new Bundle();
bundleArgs.putString("quote_id", tickerQuoteId[1]);
bundleArgs.putString("ticker_id", tickerQuoteId[0]);
TickerDialog tickerAlertDialog = new TickerDialog();
tickerAlertDialog.setArguments(bundleArgs);
tickerAlertDialog.show(fm, "fragment_ticker_alert");
}
mTickerQuoteIds = null;
}
Toast.makeText(TabActivity.this, "Quotes refreshed", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
当然,因为服务每 5 分钟循环一次,所以用户经常按下主页按钮,这会导致 onSaveInstanceState() 被调用。如果发生这种情况,并且服务尝试通过 Handler 显示 DialogFragment(在将来的某个时间),我会收到 IllegalStateException:
03-27 01:44:44.531: E/AndroidRuntime(2143): FATAL EXCEPTION: main
03-27 01:44:44.531: E/AndroidRuntime(2143): Process: com.ootpapps.stocktalker, PID: 2143
03-27 01:44:44.531: E/AndroidRuntime(2143): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
03-27 01:44:44.531: E/AndroidRuntime(2143): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1343)
03-27 01:44:44.531: E/AndroidRuntime(2143): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1361)
03-27 01:44:44.531: E/AndroidRuntime(2143): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
03-27 01:44:44.531: E/AndroidRuntime(2143): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
03-27 01:44:44.531: E/AndroidRuntime(2143): at android.support.v4.app.DialogFragment.show(DialogFragment.java:127)
03-27 01:44:44.531: E/AndroidRuntime(2143): at com.ootpapps.stocktalker.TabActivity$YahooServiceHandler.handleMessage(TabActivity.java:72)
03-27 01:44:44.531: E/AndroidRuntime(2143): at android.os.Handler.dispatchMessage(Handler.java:102)
03-27 01:44:44.531: E/AndroidRuntime(2143): at android.os.Looper.loop(Looper.java:136)
03-27 01:44:44.531: E/AndroidRuntime(2143): at android.app.ActivityThread.main(ActivityThread.java:5017)
03-27 01:44:44.531: E/AndroidRuntime(2143): at java.lang.reflect.Method.invokeNative(Native Method)
03-27 01:44:44.531: E/AndroidRuntime(2143): at java.lang.reflect.Method.invoke(Method.java:515)
03-27 01:44:44.531: E/AndroidRuntime(2143): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
03-27 01:44:44.531: E/AndroidRuntime(2143): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
03-27 01:44:44.531: E/AndroidRuntime(2143): at dalvik.system.NativeStart.main(Native Method)
我很确定这里的问题在于我的处理程序的内部非静态性质。如果托管 FragmentActivity 位于前台,则该逻辑将完美运行,但是,如果用户在任何时候点击主页按钮(仅作为一个示例),则在尝试显示()DialogFragment 时会发生 IllegalStateException。
我很感激朝着正确的方向前进,谢谢!