使用SwitchPreference的XML属性android:key会导致我的应用崩溃

时间:2015-07-21 19:11:42

标签: android

我一直在尝试在我的应用的PreferenceScreen中使用标准的Android SwitchPreference。当我将preferences.xml定义为:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <Preference
        android:icon="@mipmap/ic_launcher"
        android:id="@+id/pref_taoSettings_id"
        android:key="pref_taoSettings_key"
        android:title="@string/pref_taoSettings_title" />

    <SwitchPreference
        android:defaultValue="false"
        android:id="@+id/pref_playLevel_id"
        android:summary="Level"
        android:summaryOff="@string/pref_playLevel_beginner"
        android:summaryOn="@string/pref_playLevel_expert"
        android:title="@string/pref_playLevel_title" />

</PreferenceScreen>

当我调出我的设置活动时,我会看到以下屏幕:

[ *已删除 抱歉,我的名声不是10,所以我无法发布我的屏幕截图。基本上,PreferenceActivity会在顶部显示标题按钮,显示默认图标。在那之下,在下一个listview位置是我的SwitchPreference切换控件。我无法将文字放在控件上,因为我的最小sdk版本为7. 删除* ]

如果我然后将我的preferences.xml更新为:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

    <Preference
        android:icon="@mipmap/ic_launcher"
        android:id="@+id/pref_taoSettings_id"
        android:key="pref_taoSettings_key"
        android:title="@string/pref_taoSettings_title" />

    <SwitchPreference
        android:defaultValue="false"
        android:id="@+id/pref_playLevel_id"
        android:key="pref_playLevel_key"
        android:summary="Level"
        android:summaryOff="@string/pref_playLevel_beginner"
        android:summaryOn="@string/pref_playLevel_expert"
        android:title="@string/pref_playLevel_title" />

</PreferenceScreen>

Note: now using android:key

当我重新编译并运行应用程序时,当我单击菜单项以显示我的设置屏幕时,我崩溃了以下logcat输出(级别调试):

07-21 14:51:34.798  25317-25317/com.pcphoneconnections.threeandout W/art﹕ Before Android 4.1, method int android.support.v7.internal.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
07-21 14:51:36.957  25317-25317/com.pcphoneconnections.threeandout I/MainActivity::onOptionsItemSelected﹕ id == R.id.action_settings
07-21 14:51:36.985  25317-25317/com.pcphoneconnections.threeandout W/InputEventReceiver﹕ Attempted to finish an input event but the input event receiver has already been disposed.
07-21 14:51:37.081  25317-25317/com.pcphoneconnections.threeandout I/SettingsActivity﹕ onCreate():  Entry.
07-21 14:51:37.106  25317-25317/com.pcphoneconnections.threeandout I/SettingsActivity﹕ onCreatePreferenceFromFragment():  Entry.
07-21 14:51:37.111  25317-25317/com.pcphoneconnections.threeandout I/TaoPreferenceFragment﹕ onCreate():  Entry.
07-21 14:51:37.116  25317-25317/com.pcphoneconnections.threeandout D/AndroidRuntime﹕ Shutting down VM
07-21 14:51:37.118  25317-25317/com.pcphoneconnections.threeandout E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.pcphoneconnections.threeandout, PID: 25317
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pcphoneconnections.threeandout/com.pcphoneconnections.threeandout.SettingsActivity}: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413)
            at android.app.ActivityThread.access$800(ActivityThread.java:155)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5356)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
     Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean
            at android.app.SharedPreferencesImpl.getBoolean(SharedPreferencesImpl.java:260)
            at android.preference.Preference.getPersistedBoolean(Preference.java:1691)
            at android.preference.TwoStatePreference.onSetInitialValue(TwoStatePreference.java:187)
            at android.preference.Preference.dispatchSetInitialValue(Preference.java:1376)
            at android.preference.Preference.onAttachedToHierarchy(Preference.java:1171)
            at android.preference.PreferenceGroup.addPreference(PreferenceGroup.java:167)
            at android.preference.PreferenceGroup.addItemFromInflater(PreferenceGroup.java:108)
            at android.preference.PreferenceGroup.addItemFromInflater(PreferenceGroup.java:45)
            at android.preference.GenericInflater.rInflate(GenericInflater.java:488)
            at android.preference.GenericInflater.inflate(GenericInflater.java:326)
            at android.preference.GenericInflater.inflate(GenericInflater.java:263)
            at android.preference.PreferenceManager.inflateFromResource(PreferenceManager.java:272)
            at android.preference.PreferenceFragment.addPreferencesFromResource(PreferenceFragment.java:299)
            at com.pcphoneconnections.threeandout.SettingsActivity$TaoPreferenceFragment.onCreate(SettingsActivity.java:265)
            at android.app.Fragment.performCreate(Fragment.java:2031)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:863)
            at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
            at android.app.BackStackRecord.run(BackStackRecord.java:834)
            at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1454)
            at android.app.Activity.performStart(Activity.java:6025)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2302)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413)
            at android.app.ActivityThread.access$800(ActivityThread.java:155)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5356)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
07-21 14:51:39.324  25317-25317/com.pcphoneconnections.threeandout I/Process﹕ Sending signal. PID: 25317 SIG: 9

我正在运行Android Studio 1.2.2,其中包含以下应用设置.gradle配置:

申请插件:&#39; com.android.application&#39;

android {
    compileSdkVersion 22
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.pcphoneconnections.threeandout"
        minSdkVersion 7
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }

    //*************************************************************************
    // The following appears to identify the location of pre-built shared
    // libraries, and disables automatic ndk-build call for jni source.
    // Instructions found on several different sites for different NDK builds.
    //*************************************************************************
    sourceSets.main {
        jniLibs.srcDir 'src/main/libs' // use the jni .so compiled from the manual ndk-build command
        jni.srcDirs = [] //disable automatic ndk-build call
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

// repositories {
//     maven {
//         url "https://jitpack.io"
//     }
// }

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.0.0'
}

最后,我有以下styles.xml配置:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

        <!-- Customize your theme here. -->
        <!-- <item name="android:buttonStyle">@style/Button</item> -->

    </style>

</resources>

如果有人知道如何解决我的崩溃问题,或者甚至可以确认这是一个问题,我想知道。我无法找到关于此的任何信息,而且现在,我正在考虑转移到复选框类型二状态控件。我宁愿使用开关控制。它看起来更好。

非常感谢任何帮助。

谢谢,

鲍勃

1 个答案:

答案 0 :(得分:0)

在查看我的代码以确保我没有犯了一些愚蠢的错误之后,我又回到了原始的logcat输出(如上所示)。通过java.lang.ClassCastException下面的输出:java.lang.String无法转换为java.lang.Boolean,将我带到试图进行以下转换的Android系统库函数之一:

<head>
...
...

<script>(function(){document.documentElement.className='js'})();</script>
...
...
</head>

对这行代码进行搜索后,我发现了以下帖子:

Weird Exception: Cannot cast String to Boolean when using getBoolean

按照这些说明,我从我的设备上卸载了我的应用程序,然后重新运行了我的应用程序,并在我的设备上重新安装了它。重新安装后,错误就消失了。哇!!!