0

假设我有一个活动,它注册 BroadcastReceiver 来监听一些独立于活动生命周期的事件。Receiver 可以在 Activity 的 onStart/onStop 或 onResume/onPause 上注册。收到事件后,我想创建并显示一个片段,例如显示事件详细信息。这可行,但有时应用程序会因“IllegalStateException:onSaveInstanceState 后无法执行此操作”而崩溃。

我认为,这可能发生在活动要暂停和停止状态时,已经保存了其内部状态,但 BroadcastReceiver 尚未取消注册,此时出现新的外部事件。

片段管理器将其状态保存在 onSaveInstanceState() 上。根据官方文档,“如果调用,onSaveInstanceState() 将在 onStop() 之前发生。不能保证它是否会在 onPause() 之前或之后发生”。因此,即使我将在 onResume() 上注册接收器并在 onPause() 上取消注册,也不能保证避免 IllegalStateException,因为活动可以在 onPause() 之前保存它的内部状态。

也许,可能的解决方案是覆盖 onSaveInstanceState() 并在此处设置自己的布尔标志,如 mStateSaved。并且,当接收到新事件时,分析此标志:如果已设置,则假定活动将进入暂停-停止状态,并且不启动片段事务。

我很有趣,也许有更好的解决方案。

感谢您的关注!

更新(代码示例,片段):

@Override
protected void onStart() {
    super.onStart();
    mActionInformer.addObserver( onActionInformerUpdated );
}

@Override
protected void onStop() {
    super.onStop();        
    mActionInformer.deleteObserver( onActionInformerUpdated );
}    

Observer onActionInformerUpdated = new Observer() {
    @Override
    public void update( Observable observable, Object data ) {            
        TaskEvent event = (TaskEvent) data;
        if( event == TaskEvent.START ) {
            setSupportProgressBarIndeterminateVisibility( true );
        } else {
            setSupportProgressBarIndeterminateVisibility( false );
            // update ActionBar
            invalidateOptionsMenu();
            // handle authorisation event
            if( event == TaskEvent.AUTH ) {
                String msg = mActionInformer.getExtraMessage();
                DialogFragment dlg = AuthorisationDialog.newInstance( msg );
                dlg.show( getFragmentManager(), "Authorisation" );
            }
        }
    }
};
4

0 回答 0