离开设置活动时App Force关闭

问题描述:

这是我之后的第二个问题(已经回答):Creating SharedPreferences object inside Fragment离开设置活动时App Force关闭

在弄清楚如何在静态片段类中创建SharedPreferences对象后,我开始使用它从SettingsActivity中检索用户设置的值以设置TextEdits值。应用程序编译没有错误,并很好地启动模拟器,显示默认值(我还没有输入设置)。设置打开没有任何问题。但是,当我在ActionBar上单击“向上”时,应用程序挂起并强制关闭。之后,我无法打开它 - 它会一直关闭,直到清除应用程序数据。

它看起来像第一个应用程序打开Fragment静态类中的SharedPreference方法设置默认数据(因为他们应该,如果他们发现空),并在输入设置后返回使用“向上”(我没有改变任何值,只是保留默认的偏好xml中定义),应用程序将该默认值保存到SharedPreferences中,然后尝试检索它以在Fragments中设置TextEdits。并且它有关闭的地方。

奇怪的是,当我在静态片段类(public static class Dzien extends Fragment)中使用/ * * /注释关闭所有ifs时,应用程序工作,进入,离开Settings并且它是可以在不崩溃的情况下扫过所有碎片。更为奇怪的是,“开启”,如果在最后一种情况下5 ...:

case 5: { // Piątek 
       lekcja1.setText(getString(R.string.mat)); 
       lekcja2.setText(getString(R.string.mat)); 
       lekcja3.setText(getString(R.string.bio)); 
       lekcja4.setText(getString(R.string.pol)); 
       lekcja5.setText(getString(R.string.pol)); 
       lekcja6.setText(getString(R.string.edb)); 
       if (settings.getBoolean(WDZ, false)) { 
        lekcja7.setText(getString(R.string.wdz)); 
       } else { 
        lekcja7.setText(getString(R.string.brak)); 
       } 
       lekcja8.setText(getString(R.string.brak)); 
       lekcja9.setText(getString(R.string.brak)); 
       break; 
      } 

...不作设置碰撞而留下他们,要5片段(其中使用WDZ )。我可以切换WDZ复选框,并在相应的片段中反映它的状态。

我不知道什么可能会导致崩溃,因为如果情况1,2,3和4的块是正确的 - 唯一的区别是他们使用getInt(),而不是getBoolean()。不过,导航到相应的片段后,应用程序崩溃。

下面是来源:

MainActivity.class(在底部片段类)

package pl.konpon96.planlekcji; 

import android.content.Intent; 
import android.content.SharedPreferences; 
import android.os.Bundle; 
import android.preference.PreferenceManager; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentPagerAdapter; 
import android.support.v4.view.ViewPager; 
import android.view.LayoutInflater; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 
import android.widget.Toast; 

import java.util.Calendar; 
import java.util.Locale; 

public class MainActivity extends FragmentActivity { 

//public static final String APP_PREFERENCES = "app_preferences"; 

//public static final String GRUPA_ANGIELSKI = "grupa_angielski_list"; 
public static final String GRUPA_JEZYKOWA = "grupa_jezykowa_list"; 
public static final String GRUPA_INFORMATYKA = "grupa_informatyka_list"; 
public static final String WDZ = "wdz_checkbox"; 
//public static final String PODSWIETLANIE_LEKCJI = "podswietlanie_lekcji_checkboxs"; 

/** 
* The {@link android.support.v4.view.PagerAdapter} that will provide 
* fragments for each of the sections. We use a 
* {@link android.support.v4.app.FragmentPagerAdapter} derivative, which 
* will keep every loaded fragment in memory. If this becomes too memory 
* intensive, it may be best to switch to a 
* {@link android.support.v4.app.FragmentStatePagerAdapter}. 
*/ 
SectionsPagerAdapter mSectionsPagerAdapter; 

/** 
* The {@link ViewPager} that will host the section contents. 
*/ 
ViewPager mViewPager; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 


    // Create the adapter that will return a fragment for each of the three 
    // primary sections of the app. 
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); 

    // Set up the ViewPager with the sections adapter. 
    mViewPager = (ViewPager) findViewById(R.id.pager); 
    mViewPager.setAdapter(mSectionsPagerAdapter); 

    //Ustawianie domyślnej zakładki w zależności od dnia 

    Calendar timeNow = Calendar.getInstance(); 

    switch (timeNow.get(Calendar.DAY_OF_WEEK)) { 
     case Calendar.MONDAY: { 
      mViewPager.setCurrentItem(0, true); 
      break; 
     } 
     case Calendar.TUESDAY: { 
      mViewPager.setCurrentItem(1, true); 
      break; 
     } 
     case Calendar.WEDNESDAY: { 
      mViewPager.setCurrentItem(2, true); 
      break; 
     } 
     case Calendar.THURSDAY: { 
      mViewPager.setCurrentItem(3, true); 
      break; 
     } 
     case Calendar.FRIDAY: { 
      mViewPager.setCurrentItem(4, true); 
      break; 
     } 
     case Calendar.SATURDAY: { 
      mViewPager.setCurrentItem(0, true); 
      Toast sobotaToast = Toast.makeText(getApplicationContext(), 
        "Jest sobota - nie ma zajęć", Toast.LENGTH_SHORT); 
      sobotaToast.show(); 
      break; 
     } 
     case Calendar.SUNDAY: { 
      mViewPager.setCurrentItem(0, true); 
      Toast niedzielaToast = Toast.makeText(getApplicationContext(), 
        "Jest niedziela - nie ma zajęć", Toast.LENGTH_SHORT); 
      niedzielaToast.show(); 
      break; 
     } 


    } 

} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

@Override 

public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle item selection 
    switch (item.getItemId()) { 
     case R.id.action_settings: { 
      Intent settingsActivity = new Intent(getBaseContext(), SettingsActivity.class); 
      startActivity(settingsActivity); 
      return true; 
     } 
     case R.id.action_dzwonki: { 
      Intent dzwonkiActivity = new Intent(getBaseContext(), DzwonkiActivity.class); 
      startActivity(dzwonkiActivity); 
      return true; 
     } 
     default: 
      return super.onOptionsItemSelected(item); 
    } 
} 

/** 
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to 
* one of the sections/tabs/pages. 
*/ 
public class SectionsPagerAdapter extends FragmentPagerAdapter { 

    public SectionsPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     // getItem is called to instantiate the fragment for the given page. 
     // Return a DummySectionFragment (defined as a static inner class 
     // below) with the page number as its lone argument. 
     Fragment fragment = new Dzien(); 
     Bundle args = new Bundle(); 
     args.putInt(Dzien.ARG_SECTION_NUMBER, position + 1); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    @Override 
    public int getCount() { 
     // Show 5 total pages. 
     return 5; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     Locale l = Locale.getDefault(); 
     switch (position) { 
      case 0: 
       return getString(R.string.title_pon).toUpperCase(l); 
      case 1: 
       return getString(R.string.title_wt).toUpperCase(l); 
      case 2: 
       return getString(R.string.title_sr).toUpperCase(l); 
      case 3: 
       return getString(R.string.title_czw).toUpperCase(l); 
      case 4: 
       return getString(R.string.title_pt).toUpperCase(l); 
     } 
     return null; 
    } 
} 

/** 
* A dummy fragment representing a section of the app, but that simply 
* displays dummy text. 
*/ 
/* 
public static class DummySectionFragment extends Fragment { 

    * The fragment argument representing the section number for this 
    * fragment. 

    public static final String ARG_SECTION_NUMBER = "section_number"; 

    public DummySectionFragment() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_main_dummy, container, false); 
     TextView dummyTextView = (TextView) rootView.findViewById(R.id.section_label); 
     dummyTextView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER))); 
     return rootView; 
    } 
} 
*/ 
public static class Dzien extends Fragment { 

    public static final String ARG_SECTION_NUMBER = "section_number"; 

    public Dzien() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 

     View rootView = inflater.inflate(R.layout.fragment_main, container, false); 
     TextView lekcja1 = (TextView) rootView.findViewById(R.id.lekcja1); 
     TextView lekcja2 = (TextView) rootView.findViewById(R.id.lekcja2); 
     TextView lekcja3 = (TextView) rootView.findViewById(R.id.lekcja3); 
     TextView lekcja4 = (TextView) rootView.findViewById(R.id.lekcja4); 
     TextView lekcja5 = (TextView) rootView.findViewById(R.id.lekcja5); 
     TextView lekcja6 = (TextView) rootView.findViewById(R.id.lekcja6); 
     TextView lekcja7 = (TextView) rootView.findViewById(R.id.lekcja7); 
     TextView lekcja8 = (TextView) rootView.findViewById(R.id.lekcja8); 
     TextView lekcja9 = (TextView) rootView.findViewById(R.id.lekcja9); 

     SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity()); 

     switch (getArguments().getInt(ARG_SECTION_NUMBER)) { 
      case 1: { // Poniedziałek 
       lekcja1.setText(getString(R.string.wos)); 
       lekcja2.setText(getString(R.string.mat)); 
       lekcja3.setText(getString(R.string.ang)); 
       lekcja4.setText(getString(R.string.gw)); 
       lekcja5.setText(getString(R.string.his)); 
       lekcja6.setText(getString(R.string.wf)); 
       lekcja7.setText(getString(R.string.pp)); 
       if (settings.getInt(GRUPA_INFORMATYKA, 1) == 1) { 
        lekcja8.setText(getString(R.string.inf)); 
       } else { 
        lekcja8.setText(getString(R.string.brak)); 
       } 
       lekcja9.setText(getString(R.string.brak)); 
       break; 
      } 
      case 2: { // Wtorek 
       lekcja1.setText(getString(R.string.mat)); 
       lekcja2.setText(getString(R.string.pp)); 
       lekcja3.setText(getString(R.string.rel)); 
       lekcja4.setText(getString(R.string.wf)); 
       lekcja5.setText(getString(R.string.pol)); 
       lekcja6.setText(getString(R.string.pol)); 
       if (settings.getInt(GRUPA_JEZYKOWA, 1) == 2) { 
        lekcja7.setText(getString(R.string.ros)); 
        lekcja8.setText(getString(R.string.ros)); 
       } else { 
        lekcja7.setText(getString(R.string.brak)); 
        lekcja8.setText(getString(R.string.brak)); 
       } 
       lekcja9.setText(getString(R.string.brak)); 
       break; 
      } 
      case 3: { // Sroda 
       lekcja1.setText(getString(R.string.his)); 
       lekcja2.setText(getString(R.string.wf)); 
       lekcja3.setText(getString(R.string.mat)); 
       lekcja4.setText(getString(R.string.rel)); 
       lekcja5.setText(getString(R.string.ang)); 
       if (settings.getInt(GRUPA_JEZYKOWA, 1) == 1) { 
        lekcja6.setText(getString(R.string.niem)); 
        lekcja7.setText(getString(R.string.niem)); 
       } else { 
        lekcja6.setText(getString(R.string.brak)); 
        lekcja7.setText(getString(R.string.brak)); 
       } 
       lekcja8.setText(getString(R.string.brak)); 
       lekcja9.setText(getString(R.string.brak)); 
       break; 
      } 
      case 4: { // Czwartek 
       lekcja1.setText(getString(R.string.mat)); 
       lekcja2.setText(getString(R.string.fiz)); 
       lekcja3.setText(getString(R.string.wok)); 
       lekcja4.setText(getString(R.string.geo)); 
       lekcja5.setText(getString(R.string.ang)); 
       lekcja6.setText(getString(R.string.chem)); 
       if (settings.getInt(GRUPA_INFORMATYKA, 1) == 2) { 
        lekcja7.setText(getString(R.string.inf)); 
       } else if (((settings.getInt(GRUPA_INFORMATYKA, 1) == 2)) && ((settings.getInt(GRUPA_JEZYKOWA, 1) != 3))) { 
        lekcja7.setText(getString(R.string.brakpre)); 
       } else { 
        lekcja7.setText(getString(R.string.brak)); 
       } 
       if (settings.getInt(GRUPA_JEZYKOWA, 1) == 3) { 
        lekcja8.setText(getString(R.string.por)); 
        lekcja9.setText(getString(R.string.por)); 
       } 
       break; 
      } 
      case 5: { // Piątek 
       lekcja1.setText(getString(R.string.mat)); 
       lekcja2.setText(getString(R.string.mat)); 
       lekcja3.setText(getString(R.string.bio)); 
       lekcja4.setText(getString(R.string.pol)); 
       lekcja5.setText(getString(R.string.pol)); 
       lekcja6.setText(getString(R.string.edb)); 
       if (settings.getBoolean(WDZ, false)) { 
        lekcja7.setText(getString(R.string.wdz)); 
       } else { 
        lekcja7.setText(getString(R.string.brak)); 
       } 
       lekcja8.setText(getString(R.string.brak)); 
       lekcja9.setText(getString(R.string.brak)); 
       break; 
      } 


     } 

     return rootView; 
    } 
} 
} 

SettingsActivity.class - 有除去预编译的偏好片段后一点的混乱 - 我使用不推荐的API导致它不会使用平板电脑UI。

package pl.konpon96.planlekcji; 

import android.annotation.TargetApi; 
import android.content.Context; 
import android.content.res.Configuration; 
import android.os.Build; 
import android.os.Bundle; 
import android.preference.ListPreference; 
import android.preference.Preference; 
import android.preference.PreferenceActivity; 
import android.preference.PreferenceFragment; 
import android.preference.PreferenceManager; 
import android.support.v4.app.NavUtils; 
import android.view.MenuItem; 

/** 
* A {@link PreferenceActivity} that presents a set of application settings. On 
* handset devices, settings are presented as a single list. On tablets, 
* settings are split by category, with category headers shown to the left of 
* the list of settings. 
* <p/> 
* See <a href="http://developer.android.com/design/patterns/settings.html"> 
* Android Design: Settings</a> for design guidelines and the <a 
* href="http://developer.android.com/guide/topics/ui/settings.html">Settings 
* API Guide</a> for more information on developing a Settings UI. 
*/ 
@SuppressWarnings("deprecation") 
public class SettingsActivity extends PreferenceActivity { 

private static final boolean ALWAYS_SIMPLE_PREFS = true; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setupActionBar(); 

    addPreferencesFromResource(R.xml.pref_general); 

    bindPreferenceSummaryToValue(findPreference("grupa_angielski_list")); 
    bindPreferenceSummaryToValue(findPreference("grupa_jezykowa_list")); 
    bindPreferenceSummaryToValue(findPreference("grupa_informatyka_list")); 
} 

/** 
* Set up the {@link android.app.ActionBar}, if the API is available. 
*/ 
@TargetApi(Build.VERSION_CODES.HONEYCOMB) 
private void setupActionBar() { // Przycisk UP na ActionBar 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
     getActionBar().setDisplayHomeAsUpEnabled(true); 
    } 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { // Akcja użytkownika - przycisk UP 
    switch (item.getItemId()) { 
     case android.R.id.home: 
      // This ID represents the Home or Up button. In the case of this 
      // activity, the Up button is shown. Use NavUtils to allow users 
      // to navigate up one level in the application structure. For 
      // more details, see the Navigation pattern on Android Design: 
      // 
      // http://developer.android.com/design/patterns/navigation.html#up-vs-back 
      // 
      // TODO: If Settings has multiple levels, Up should navigate up 
      // that hierarchy. 
      NavUtils.navigateUpFromSameTask(this); 
      return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 


/** 
* Shows the simplified settings UI if the device configuration if the 
* device configuration dictates that a simplified, single-pane UI should be 
* shown. 
*/ 

/** 
* {@inheritDoc} 
*/ 
@Override 
public boolean onIsMultiPane() { 
    return isXLargeTablet(this) && !isSimplePreferences(this); 
} 

/** 
* Helper method to determine if the device has an extra-large screen. For 
* example, 10" tablets are extra-large. 
*/ 
private static boolean isXLargeTablet(Context context) { 
    return (context.getResources().getConfiguration().screenLayout 
      & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE; 
} 

/** 
* Determines whether the simplified settings UI should be shown. This is 
* true if this is forced via {@link #ALWAYS_SIMPLE_PREFS}, or the device 
* doesn't have newer APIs like {@link PreferenceFragment}, or the device 
* doesn't have an extra-large screen. In these cases, a single-pane 
* "simplified" settings UI should be shown. 
*/ 
private static boolean isSimplePreferences(Context context) { 
    return ALWAYS_SIMPLE_PREFS 
      || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB 
      || !isXLargeTablet(context); 
} 

/** 
* A preference value change listener that updates the preference's summary 
* to reflect its new value. 
*/ 
private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() { 
    @Override 
    public boolean onPreferenceChange(Preference preference, Object value) { 
     String stringValue = value.toString(); 

     if (preference instanceof ListPreference) { 
      // For list preferences, look up the correct display value in 
      // the preference's 'entries' list. 
      ListPreference listPreference = (ListPreference) preference; 
      int index = listPreference.findIndexOfValue(stringValue); 

      // Set the summary to reflect the new value. 
      preference.setSummary(
        index >= 0 
          ? listPreference.getEntries()[index] 
          : null); 

     } else { 
      // For all other preferences, set the summary to the value's 
      // simple string representation. 
      preference.setSummary(stringValue); 
     } 
     return true; 
    } 
}; 

/** 
* Binds a preference's summary to its value. More specifically, when the 
* preference's value is changed, its summary (line of text below the 
* preference title) is updated to reflect the value. The summary is also 
* immediately updated upon calling this method. The exact display format is 
* dependent on the type of preference. 
* 
* @see #sBindPreferenceSummaryToValueListener 
*/ 
private static void bindPreferenceSummaryToValue(Preference preference) { 
    // Set the listener to watch for value changes. 
    preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener); 

    // Trigger the listener immediately with the preference's 
    // current value. 
    sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, 
      PreferenceManager 
        .getDefaultSharedPreferences(preference.getContext()) 
        .getString(preference.getKey(), "")); 
} 

} 

首pref_general.xml文件:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> 

<PreferenceCategory android:title="@string/pref_header_personalizacja"> 

    <ListPreference 
      android:key="grupa_jezykowa_list" 
      android:title="@string/pref_title_grupa_jezykowa" 
      android:defaultValue="1" 
      android:entries="@array/pref_grupa_jezykowa_list_titles" 
      android:entryValues="@array/pref_grupa_jezykowa_values" 
      android:negativeButtonText="@null" 
      android:positiveButtonText="@null"/> 


    <ListPreference 
      android:key="grupa_angielski_list" 
      android:title="@string/pref_title_grupa_angielski" 
      android:defaultValue="1" 
      android:entries="@array/pref_grupa_angielski_list_titles" 
      android:entryValues="@array/pref_grupa_angielski_values" 
      android:negativeButtonText="@null" 
      android:positiveButtonText="@null"/> 

    <ListPreference 
      android:key="grupa_informatyka_list" 
      android:title="@string/pref_title_grupa_informatyka" 
      android:defaultValue="1" 
      android:entries="@array/pref_grupa_informatyka_list_titles" 
      android:entryValues="@array/pref_grupa_informatyka_values" 
      android:negativeButtonText="@null" 
      android:positiveButtonText="@null"/> 

    <CheckBoxPreference 
      android:key="wdz_checkbox" 
      android:title="@string/pref_title_wdz" 
      android:summary="@string/pref_description_wdz" 
      android:defaultValue="false"/> 

</PreferenceCategory> 

这里是仿真器的开放应用首次进入设置后的logcat然后回去:

https://dl.dropboxusercontent.com/u/6200994/logcat.txt

+0

忘记了最重要的东西...其中来自logcat的日志?而另一件事...存储在代码中的数据?你想如何迅速改变? – Selvin

+0

你有logcat的? –

+0

谢谢提醒。 – Konpon96

好的,现在已经很清楚了。由SettingsActivity自动保存的SharedPreferences是String类型的,所以应该使用getString()而不是getInt()。更重要的是,如果要比较两个字符串,应该使用.equal()方法而不是==运算符。

例如...:

if (settings.getInt(GRUPA_INFORMATYKA, 1) == 1) { 
       lekcja8.setText(getString(R.string.inf)); 
      } else { 
       lekcja8.setText(getString(R.string.brak)); 
      } 

...应该是:

if (settings.getString(GRUPA_INFORMATYKA, "1").equals("1")) { 
       lekcja8.setText(getString(R.string.inf)); 
      } else { 
       lekcja8.setText(getString(R.string.brak)); 
      } 

感谢谁提醒我关于logcat的人。 :)