【背景】
之前折腾了:
【基本解决】Android中PreferenceFragment界面透明导致界面很混乱
但是接着又遇到其他方面的问题:
04-24 15:38:13.553: W/dalvikvm(3423): threadid=1: thread exiting with uncaught exception (group=0xb2f44288)
04-24 15:38:13.553: E/AndroidRuntime(3423): FATAL EXCEPTION: main
04-24 15:38:13.553: E/AndroidRuntime(3423): java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx.yyy.zzz/xxx.yyy.zzz.aa.MainActivity}: java.lang.IllegalStateException: setSelectedNavigationIndex not valid for current navigation mode
04-24 15:38:13.553: E/AndroidRuntime(3423): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
04-24 15:38:13.553: E/AndroidRuntime(3423): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
04-24 15:38:13.553: E/AndroidRuntime(3423): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3512)
04-24 15:38:13.553: E/AndroidRuntime(3423): at android.app.ActivityThread.access$700(ActivityThread.java:130)
04-24 15:38:13.553: E/AndroidRuntime(3423): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201)
04-24 15:38:13.553: E/AndroidRuntime(3423): at android.os.Handler.dispatchMessage(Handler.java:99)
04-24 15:38:13.553: E/AndroidRuntime(3423): at android.os.Looper.loop(Looper.java:137)
04-24 15:38:13.553: E/AndroidRuntime(3423): at android.app.ActivityThread.main(ActivityThread.java:4745)
04-24 15:38:13.553: E/AndroidRuntime(3423): at java.lang.reflect.Method.invokeNative(Native Method)
04-24 15:38:13.553: E/AndroidRuntime(3423): at java.lang.reflect.Method.invoke(Method.java:511)
04-24 15:38:13.553: E/AndroidRuntime(3423): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
04-24 15:38:13.553: E/AndroidRuntime(3423): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
04-24 15:38:13.553: E/AndroidRuntime(3423): at dalvik.system.NativeStart.main(Native Method)
04-24 15:38:13.553: E/AndroidRuntime(3423): Caused by: java.lang.IllegalStateException: setSelectedNavigationIndex not valid for current navigation mode
04-24 15:38:13.553: E/AndroidRuntime(3423): at com.android.internal.app.ActionBarImpl.setSelectedNavigationItem(ActionBarImpl.java:362)
04-24 15:38:13.553: E/AndroidRuntime(3423): at xxx.yyy.zzz.aa.MainActivity.onRestoreInstanceState(MainActivity.java:654)
04-24 15:38:13.553: E/AndroidRuntime(3423): at android.app.Activity.performRestoreInstanceState(Activity.java:900)
04-24 15:38:13.553: E/AndroidRuntime(3423): at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1130)
04-24 15:38:13.553: E/AndroidRuntime(3423): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2037)
04-24 15:38:13.553: E/AndroidRuntime(3423): ... 12 more如图:
对应代码是:
public class SettingFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
// setTheme(R.style.AppBaseTheme);
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
......
......
switchLanguage.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference,
Object newValue) {
......
res.updateConfiguration(config, res.getDisplayMetrics());
SettingFragment.this.getActivity().recreate();
return true;
}
});
}
......
}看起来是由于:
SettingFragment.this.getActivity().recreate();
而导致挂掉的。
【解决过程】
1.然后重新调试期间,发现:
SettingFragment.this.getActivity()
得到的就是MainActivity,而接着出错,显示的是:
java.lang.IllegalStateException: setSelectedNavigationIndex not valid for current navigation mode
看了就是对于MainActivity来说的了。
2.继续调试,发现好像是在:
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Restore the previously serialized current tab position.
if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
getActionBar().setSelectedNavigationItem(
savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
}
}挂掉的。
所以暂时注释掉:
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
// // Restore the previously serialized current tab position.
// if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
// getActionBar().setSelectedNavigationItem(
// savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
// }
}然后看看结果:
结果又发现,会先执行:
@Override
public void onSaveInstanceState(Bundle outState) {
// Serialize the current tab position.
outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar()
.getSelectedNavigationIndex());
}然后才是onRestoreInstanceState。
3.然后去改为:
@Override
public void onSaveInstanceState(Bundle outState) {
// Serialize the current tab position.
//outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar().getSelectedNavigationIndex());
if(null != mTabHost){
outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, mTabHost.getCurrentTab());
}
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Restore the previously serialized current tab position.
if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
//getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
if(null != mTabHost){
mTabHost.setCurrentTab(savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
}
}
}看看效果:
基本是解决了crash的问题。
不过对于tab的index还是没法保存。
4.最后改为:
public class MainActivity extends Activity implements ISubscriber{
private static final String STATE_SELECTED_TAB_INDEX = "selected_tab_index";
private int mPreSelectedTabIdx = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPreSelectedTabIdx = restoreSavedSelectedTabIdx(savedInstanceState);
}
@Override
public void onSaveInstanceState(Bundle outState) {
// Serialize the current tab position.
//outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar().getSelectedNavigationIndex());
if(null != mTabHost){
int curTabIdx = mTabHost.getCurrentTab();
mPreSelectedTabIdx = curTabIdx;
outState.putInt(STATE_SELECTED_TAB_INDEX, curTabIdx);
}
}
private int restoreSavedSelectedTabIdx(Bundle savedInstanceState){
int savedTabIdx = mPreSelectedTabIdx;
if(null != savedInstanceState){
if (savedInstanceState.containsKey(STATE_SELECTED_TAB_INDEX)) {
//getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
savedTabIdx = savedInstanceState.getInt(STATE_SELECTED_TAB_INDEX);
}
}
return savedTabIdx;
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Restore the previously serialized current tab position.
if (savedInstanceState.containsKey(STATE_SELECTED_TAB_INDEX)) {
//getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
if(null != mTabHost){
int savedTabIdx = savedInstanceState.getInt(STATE_SELECTED_TAB_INDEX);
mTabHost.setCurrentTab(savedTabIdx);
}
}
}
private void generateMainTabUI(){
mTabHost.setCurrentTab(mPreSelectedTabIdx);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
......
case R.id.menu_settings:
showPreference();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void showPreference(){
getFragmentManager()
.beginTransaction()
.setTransition(
FragmentTransaction.TRANSIT_FRAGMENT_FADE)
//.replace(android.R.id.content, new SettingFragment())
.add(android.R.id.content, new SettingFragment())
//.replace(android.R.id.tabcontent, new SettingFragment())
//.replace(R.id.preference_layout, new SettingFragment())
.addToBackStack(null).commit();
}
}
【总结】
此处对于Activity的recreate会挂的原因是:
Activity代码中之前有和restoreSavedSelectedTabIdx方面的代码,其中有setSelectedNavigationItem
但是该代码是无效的,因为我此处的tab不是用的ActionBar的,是我另外自己用tabHost去实现的。
所以,最简单的办法是:要么去掉该代码
不过,如果继续想要保存tab的index等信息,则需要自己此处额外添加一些代码,就可以了。。
转载请注明:在路上 » 【已解决】Android中getActivity().recreate()时出错:java.lang.IllegalStateException: setSelectedNavigationIndex not valid for current navigation mode
