setContentView Вызывает сбой в PreferenceActivity на Android 8.0

Мой код довольно прост.

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"/>

... другие методы, которые переопределяются, но просто реализуют super.<method>() (А также isValidFragment который, кажется, работает правильно)

По сути, если устройство не является планшетом, оно загружает панель инструментов для PreferenceActivity,

Этот код отлично работает на всех устройствах, кроме тех, которые работают под управлением Android 8.0. На 8.0 я получаю следующую ошибку:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.ViewGroup.setLayoutTransition(android.animation.LayoutTransition)' on a null object reference

Полное сообщение об ошибке:

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)

Эта ошибка возникает после onCreate() метод работает, но вынимает строку setContentView(R.layout.preference_no_buttons); исправляет сбой. Я попытался переместить этот код в другие методы (onCreate а также onPostCreate) но я все равно получаю ту же ошибку. Кто-нибудь знает, как исправить эту ошибку? Опять же, это происходит только на Android 8.0. Все остальные версии обрабатывают это правильно. Он также работает правильно на планшетном устройстве (даже на планшете с версией 8.0, поскольку в этом сценарии код, вызывающий сбой, никогда не запускается).

Сейчас я только что изменился if(!getResources().getBoolean(R.bool.tablet)) в if(!getResources().getBoolean(R.bool.tablet) && Build.VERSION.SDK_INT < Build.VERSION_CODES.O) чтобы не загружать панель инструментов на Android O, но было бы неплохо исправить это, не включая удаление панели инструментов.

1 ответ

Решение

По словам Google, это предполагаемое поведение, хотя оно работало должным образом в предыдущих версиях Android: https://issuetracker.google.com/issues/36873126

После прочтения я обнаружил, что PreferenceActivity не следует использовать для устройств, использующих версию Android более позднюю, чем 3.0.

Поскольку я не поддерживаю устройства ниже и Android 4.0, я изменил свой PreferenceActivity в равнине Activity который использует PreferenceFragment как описано здесь: https://developer.android.com/guide/topics/ui/settings.html

Другие вопросы по тегам