0

我有一个前台服务,每 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。

我很感激朝着正确的方向前进,谢谢!

4

1 回答 1

0

所以,我想回答我关于如何以最简单的方式实现这一点的问题。

我的目标是在服务请求时显示 DialogFragment。这样做的困难在于,我的处理程序是托管 DialogFragment 的 Activity 的内部类,当我尝试调用 DialogFragment 时,这会导致生命周期问题。

为了在几乎没有任何工作的情况下实现这一点,我创建了一个看起来像 Dialog 的透明 Activity,而不是使用 DialogFragment。这简化了一切,因为在启动 Activity 时我不必担心 IllegalStateException。所以现在一切都按预期工作!

感谢您的建议,但最终,如果您遇到此异常,请查看是否可以简单地创建一个虚拟 Activity 来启动您的目标 Fragment。这将极大地简化生命周期问题!

于 2014-03-29T18:24:27.393 回答