有人可以为我回答这个问题:
出于测试目的,我创建了一个带有for循环的活动,其中我创建了10个AlertDialogs或10个DialogFragments.活动开始后,我立即按主页按钮在后台发送应用程序.如果我正在运行showDialog()方法来创建DialogFragments,则应用程序将崩溃:
IllegalStateException: Can not perform this action after onSaveInstanceState
Run Code Online (Sandbox Code Playgroud)
这是预期的行为.
但是,如果我运行showAlert()方法来创建AlertDialogs,就像我将应用程序发送到后台之前一样,应用程序不会崩溃.当我回到活动时,我可以看到所有10个AlertDialogs.
问题是为什么活动状态丢失发生在DialogFragment而不是AlertDialog?
保存活动状态后,我仍在更改UI.我测试过的平台是Android 4.4.2
public class Main extends FragmentActivity
{
private FragmentActivity activity = this;
private MyAsynk myAsynk;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
myAsynk = new MyAsynk();
myAsynk.execute();
}
private class MyAsynk extends AsyncTask<Void, Void, Void>
{
private boolean run = false;
public MyAsynk()
{
run = true;
}
@Override
protected Void doInBackground(Void... params)
{
for(int i = 0; i < 10 && run; i++)
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
// showAlert("loop " + i);
showDialog("loop " + i);
}
return null;
}
public void stop()
{
run = false;
}
}
@Override
public void onBackPressed()
{
super.onBackPressed();
if(null != myAsynk)
{
myAsynk.stop();
myAsynk = null;
}
}
private void showAlert(final String txt)
{
try
{
Main.this.runOnUiThread(new Runnable()
{
@Override
public void run()
{
new AlertDialog.Builder(activity).setMessage(txt)
.setPositiveButton("Ok", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
try
{
if(null != dialog)
{
dialog.dismiss();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
})
.show();
}
});
}
catch(Exception e)
{
e.printStackTrace();
}
}
private void showDialog(final String txt)
{
try
{
Main.this.runOnUiThread(new Runnable()
{
@Override
public void run()
{
MyDialogFragment newFragment = MyDialogFragment.newInstance(txt);
FragmentTransaction ft = Main.this.getSupportFragmentManager().beginTransaction();
newFragment.show(ft, "newFragment");
}
});
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
MyDialogFragment.java:
public class MyDialogFragment extends DialogFragment
{
private MyDialogFragment instance;
public static MyDialogFragment newInstance(String text)
{
MyDialogFragment f = new MyDialogFragment();
Bundle args = new Bundle();
args.putString("text", text);
f.setArguments(args);
return f;
}
public MyDialogFragment()
{
instance = this;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View v = inflater.inflate(R.layout.my_dialog_fragment, container, false);
TextView tv = (TextView) v.findViewById(R.id.tv);
Button bu = (Button) v.findViewById(R.id.bu);
bu.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
try
{
if(null != instance && instance.isVisible())
{
instance.dismiss();
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
});
tv.setText(getArguments().getString("text"));
return v;
}
}
Run Code Online (Sandbox Code Playgroud)
答案很简单,尽管有点平淡。
常见的java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState异常实际上是由FragmentManager类抛出的。Alex Lockwood在这篇文章中很好地解释了原因。
DialogFragments是片段(因此由 管理FragmentManager)。因此,以这种方式显示对话框可能会引发异常。然而,它的实现AlertDialog完全不同:它根本不使用 Fragments(事实上,它实际上早于 Fragments)。因此,没有例外。
| 归档时间: |
|
| 查看次数: |
936 次 |
| 最近记录: |