My code is pretty simple.
public class SettingsMenuNew extends PreferenceActivity
{
...
@Override
public void onBuildHeaders(List<Header> target)
{
if(!getResources().getBoolean(R.bool.tablet)) {
setContentView(R.layout.preference_no_buttons);
}
loadHeadersFromResource(R.xml.settings_menu, target);
}
....
}
preference_no_buttons.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<include
layout="@layout/settings_toolbar"
android:id="@+id/toolbar" />
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
settings_toolbar.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:title="@string/Settings"
app:titleTextColor="@color/menuWhite"/>
The ...
are other methods that are overridden, but just implement the super.<method>()
(And isValidFragment
which seems to work properly)
Basically, if the device isn't a tablet device, it loads a toolbar for the PreferenceActivity
.
This code works fine on all devices except those running Android 8.0. On 8.0 I get the following error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.ViewGroup.setLayoutTransition(android.animation.LayoutTransition)' on a null object reference
Full Error message:
16507/<myApp> E/AndroidRuntime: FATAL EXCEPTION: main
Process: <myApp>, PID: 16507
java.lang.RuntimeException: Unable to start activity ComponentInfo{<myApp>/<myApp>.SettingsMenuNew}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.ViewGroup.setLayoutTransition(android.animation.LayoutTransition)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.ViewGroup.setLayoutTransition(android.animation.LayoutTransition)' on a null object reference
at android.preference.PreferenceActivity.onCreate(PreferenceActivity.java:653)
at <myApp>.SettingsMenuNew.onCreate(SettingsMenuNew.java:33)
at android.app.Activity.performCreate(Activity.java:6975)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
This error occurs after the onCreate()
method runs, but taking out the line setContentView(R.layout.preference_no_buttons);
fixes the crash. I have tried moving this code to other methods (onCreate
and onPostCreate
) but I still get the same error. Does anyone know how to fix this error? Again, it's only happening on Android 8.0. All other versions handle it properly. It also works properly on a tablet device (even a tablet running 8.0, because the offending code is never run in that scenario.)
For now I've just changed if(!getResources().getBoolean(R.bool.tablet))
to if(!getResources().getBoolean(R.bool.tablet) && Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
to avoid loading the toolbar on Android O, but a fix which doesn't involve removing the toolbar would be nice.
According to Google, this is the intended behavior, even though it worked properly in previous versions of Android: https://issuetracker.google.com/issues/36873126
After doing some more reading, I found that
PreferenceActivity
shouldn't be used for devices using a version of Android later than 3.0.Since I am not supporting devices lower and Android 4.0 I have since changed my
PreferenceActivity
into a plainActivity
which uses aPreferenceFragment
as described here: https://developer.android.com/guide/topics/ui/settings.html