我面临着DialogFragment / getSupportFragmentManager / Android版本4.x的问题
01-10 19:46:48.228: E/AndroidRuntime(9879): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
01-10 19:46:48.228: E/AndroidRuntime(9879): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1314)
01-10 19:46:48.228: E/AndroidRuntime(9879): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1325)
01-10 19:46:48.228: E/AndroidRuntime(9879): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548)
01-10 19:46:48.228: E/AndroidRuntime(9879): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:532)
01-10 19:46:48.228: E/AndroidRuntime(9879): at android.support.v4.app.DialogFragment.show(DialogFragment.java:127)
01-10 19:46:48.228: E/AndroidRuntime(9879): at com.v1.mypck.TermsAndConditions.showDialog(TermsAndConditions.java:256)
01-10 19:46:48.228: E/AndroidRuntime(9879): at com.v1.mypck.TermsAndConditions.handleMessage(TermsAndConditions.java:62)
01-10 19:46:48.228: E/AndroidRuntime(9879): at com.v1.mypck.TermsAndConditions$IncomingHandler.handleMessage(TermsAndConditions.java:53)
01-10 19:46:48.228: E/AndroidRuntime(9879): at android.os.Handler.dispatchMessage(Handler.java:99)
01-10 19:46:48.228: E/AndroidRuntime(9879): at android.os.Looper.loop(Looper.java:137)
01-10 19:46:48.228: E/AndroidRuntime(9879): at android.app.ActivityThread.main(ActivityThread.java:4441)
01-10 19:46:48.228: E/AndroidRuntime(9879): at java.lang.reflect.Method.invokeNative(Native Method)
01-10 19:46:48.228: E/AndroidRuntime(9879): at java.lang.reflect.Method.invoke(Method.java:511)
01-10 19:46:48.228: E/AndroidRuntime(9879): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-10 19:46:48.228: E/AndroidRuntime(9879): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-10 19:46:48.228: E/AndroidRuntime(9879): at dalvik.system.NativeStart.main(Native Method)
在下面的代码中,当我按下它时,它尝试完成当前活动并返回上一个活动,它会抛出错误 .
代码适用于旧版本(4.x之前) .
有人可以指导我正确的方向 .
public class TermsAndConditions extends SherlockFragmentActivity implements LoaderManager.LoaderCallbacks<JSONObject>{
static final String TAG = "TermsAndConditions";
private static int titleResource;
private static int messageResource;
private IncomingHandler handler = null;
private static final int SHOW_NETWORK_DIALOG = 3;
static class IncomingHandler extends Handler {
private final WeakReference<TermsAndConditions> mTarget;
IncomingHandler(TermsAndConditions target) {
mTarget = new WeakReference<TermsAndConditions>(target);
}
@Override
public void handleMessage(Message msg) {
TermsAndConditions target = mTarget.get();
if (target != null) {
target.handleMessage(msg);
}
}
}
public void handleMessage(Message msg) {
switch (msg.what) {
case SHOW_NETWORK_DIALOG:
titleResource = R.string.msg_alert_no_network_title;
messageResource = R.string.msg_alert_no_network_message;
showDialog();
break;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.web_view);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportLoaderManager().initLoader(0, null, this);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void loadViewData() {
//Logic to load content.
}
@Override
public Loader<JSONObject> onCreateLoader(int arg0, Bundle arg1) {
if (handler == null){
handler = new IncomingHandler(TermsAndConditions.this);
}
return new JsonLoader(this);
}
@Override
public void onLoadFinished(Loader<JSONObject> arg0, JSONObject jsonData) {
if(jsonDataObject==null || jsonDataObject.length()==0) {
handler.sendEmptyMessage(SHOW_NETWORK_DIALOG);
} else {
loadViewData();
}
}
@Override
public void onLoaderReset(Loader<JSONObject> arg0) {
if(jsonDataObject==null || jsonDataObject.length()==0) {
handler.sendEmptyMessage(SHOW_NETWORK_DIALOG);
} else {
loadViewData();
}
}
public static class JsonLoader extends AsyncTaskLoader<JSONObject> {
public JsonLoader(Context context) {
super(context);
}
@Override
protected void onStartLoading() {
if (jsonDataObject != null) {
deliverResult(jsonDataObject);
}
if (takeContentChanged() || jsonDataObject == null) {
forceLoad();
}
}
@Override
public JSONObject loadInBackground() {
try {
return response.getJSONObject("result");
} catch (JSONException e) {
return null;
} catch (Throwable e) {
return null;
}
}
@Override
public void deliverResult(JSONObject newJsonData) {
if (isReset()) {
if (jsonDataObject != null) {
onReleaseResources(jsonDataObject);
}
}
JSONObject oldData = jsonDataObject;
jsonDataObject = newJsonData;
if (isStarted()) {
super.deliverResult(jsonDataObject);
}
if (oldData != null) {
onReleaseResources(oldData);
}
}
@Override
protected void onStopLoading() {
cancelLoad();
}
@Override public void onCanceled(JSONObject jsonData) {
super.onCanceled(jsonData);
onReleaseResources(jsonData);
}
@Override protected void onReset() {
super.onReset();
onStopLoading();
if (jsonDataObject != null) {
onReleaseResources(jsonDataObject);
jsonDataObject = null;
}
}
protected void onReleaseResources(JSONObject jsonData) {
jsonData = null;
}
}
public static class MyAlertDialogFragment extends DialogFragment {
public static MyAlertDialogFragment newInstance(int title) {
MyAlertDialogFragment frag = new MyAlertDialogFragment();
Bundle args = new Bundle();
args.putInt("title", title);
frag.setArguments(args);
return frag;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int title = getArguments().getInt("title");
return new AlertDialog.Builder(getActivity())
.setTitle(title)
.setMessage(messageResource)
.setPositiveButton(R.string.alert_dialog_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
}
)
.create();
}
}
public void showDialog() {
DialogFragment newFragment = MyAlertDialogFragment.newInstance(titleResource);
newFragment.show(getSupportFragmentManager(), "my_dialog");
}
}
10 回答
在 Activity 中,在显示 dialog 之前,你可以做这样的事情
这对我有用 .
以下是另一个帖子中的答案:
Actions in onActivityResult and "Error Can not perform this action after onSaveInstanceState"
也在这里:
Refreshing my fragment not working like I thought it should
这是解决此问题的示例:
我遇到了同样的问题,我改变了代码如下
至:
完成的代码对我来说效果不错,希望有所帮助
可能是,响应HandleMessage的处理程序与被破坏的活动相关联 .
即:如果你旋转屏幕,旧的被破坏的活动将处理消息,然后你将调用showDialog,并抛出异常:
在旧的被破坏的活动调用了他的onSaveInstanceState之后,您正在创建一个对话框 .
尝试使用新创建的活动替换回调,以确保始终在alive活动中创建对话框 .
如果你没有旋转,请在onSaveInstance上放置一个标志,如“save”,并在onRestoreInstance上禁用它 . 在handleMessage方法中,如果启用了“save”标志,则不显示该对话框,只需打开另一个标志,指示必须在onResume上创建对话框 . 然后在onResume方法中,检查是否在该过程的中间,您应该创建对话框,如果是,则在onResume方法上显示它 .
在这种情况下,post()方法的目标是等待Activity或Fragment的onResume()完成 . 如果你想从Fragment中显示DialogFragment,它可以工作 . 当您想要在系统对话框解除后显示对话框时 .
当发布延迟Runnables handler.postDelayed(Runnable runnable,long delayed)时,我遇到了同样的问题 .
我用这种方式解决了这个问题:
在onSaveInstanceState中我取消延迟的任务
在onRestoreInstanceState中,如果在销毁活动时出现延迟任务,则重新创建任务
答太晚,但可能是正确的答案 . 我创建了一个父类,并从中扩展了对话框片段
}
onPostResume() 使用post resume方法来完成你的工作..我认为你在onRestart或onResume中调用show dialog方法,所以避免它并使用 onPostResume() 来显示你的对话框 .
您可以检查当前活动是否为isActive(),并且仅在这种情况下启动DialogFragment的片段事务 . 我有一个类似的问题,这个检查解决了我的情况 .
有用:
但是仍然很糟糕,因为得到错误“活动已被破坏”
所以我的解决方案是添加检查
if (!isFinishing()&&!isDestroyed())
关于解雇: