离开SettingsActivity时,App force会关闭

时间:2013-07-04 14:39:17

标签: java android crash android-fragments sharedpreferences

这是我的第二个问题(已经回答):Creating SharedPreferences object inside Fragment

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

看起来像第一个应用程序在Fragment静态类设置默认数据后打开SharedPreference方法(如果它们找到null就应该这样),并在输入设置并返回后使用“up”(我没有更改任何值,只需保留偏好xml中定义的默认值,app会将默认值保存到SharedPreferences中,然后尝试检索它以在Fragments中设置TextEdits。并且有它关闭的地方。

奇怪的是,当我使用/ * * / comments“关闭”静态Fragment类(公共静态类Dzien扩展Fragment)中的所有ifs时,app工作,进入,离开设置,这是可能的在不崩溃的情况下轻扫所有碎片。更奇怪的是,如果在最后一种情况下“开启”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;
            }

...在离开它们并转到5th Fragment(使用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导致它不会使用平板电脑用户界面。

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

1 个答案:

答案 0 :(得分:0)

好的,现在一切都清楚了。 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的人。 :)