A
FragmentActivity
正确充气 android.widget.Toolbar
在第一次部署 androidx.preference.PreferenceFragmentCompat
后停止这样做。
堆栈跟踪表明失败的根本原因是
android.widget.RtlSpacingHelper
的空实例:
android.view.InflateException: Binary XML file line #18: Binary XML file line #18: Error inflating class <unknown>
Caused by: android.view.InflateException: Binary XML file line #18: Error inflating class <unknown>
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
at android.view.LayoutInflater.createView(LayoutInflater.java:652)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:794)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:734)
at android.view.LayoutInflater.inflate(LayoutInflater.java:496)
at android.view.LayoutInflater.inflate(LayoutInflater.java:427)
at android.view.LayoutInflater.inflate(LayoutInflater.java:378)
at common.WideFrag.onCreateView(WideFrag.java:168)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:3104)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:524)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1899)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1817)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1760)
at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:547)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6780)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.RtlSpacingHelper.setDirection(boolean)' on a null object reference
at android.widget.Toolbar.onRtlPropertiesChanged(Toolbar.java:825)
at android.view.View.resolvePadding(View.java:16493)
at android.view.ViewGroup.resolvePadding(ViewGroup.java:7006)
at android.view.View.initializeScrollbarsInternal(View.java:5740)
at android.view.View.<init>(View.java:4988)
at android.view.ViewGroup.<init>(ViewGroup.java:579)
at android.widget.Toolbar.<init>(Toolbar.java:291)
at android.widget.Toolbar.<init>(Toolbar.java:287)
at android.widget.Toolbar.<init>(Toolbar.java:283)
... 23 more
WideFrag.onCreateView: InflateException for toolbar.xml=2131558714 (0x7f0d013a): android.view.InflateException: Binary XML file line #18: Error inflating class <unknown>
Toolbar('toolbar.xml')如下:
<android.widget.Toolbar android:id="@+id/toolbar"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/listItemHeightMenu"
android:background="@color/khaki_tp"
android:elevation="6dp"
android:visibility="gone"
> <!-- NB: Stacktrace refers to this line -->
</android.widget.Toolbar>
这里是有问题的 Fragment 的拆解极简版本。它包含自己的实例化器,以方便任何希望重现问题的人。如果您的应用程序使用 android.widget.Toolbar 那么它将在该片段运行后停止工作,但请注意 androidx.appcompat.widget.Toolbar 仍将正常膨胀!
package yourPackage;
import static java.lang.String.format;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.preference.PreferenceFragmentCompat;
import yourPackage.R;
/** Prove bug upsetting Toolbar inflation (1/2) */
public class PrefsBug1 extends PreferenceFragmentCompat {
public static String TAG = "Buggy-tag1";
public static void newInstance(FragmentActivity A) {
PrefsBug1 frag = new PrefsBug1();
int ctr = R.id.fragment_container;
FragmentManager fm = A.getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(ctr, frag, TAG);
ft.addToBackStack(TAG);
String msg;
try { ft.commit();
msg=(format("Added '%s' to container %d [%s] (backstack was %d).", TAG, ctr, "R.id.fragment_container", fm.getBackStackEntryCount()));}
catch (Exception e) { msg = e.getMessage(); }
Log.d(TAG, msg);
}
@Override
public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
setPreferencesFromResource(R.xml.pref_debug, rootKey);
}
}
这里是示例 PrefScreen('pref_debug.xml'):
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="A PREFERENCE">
<EditTextPreference
android:key="pref_fontScale"
android:title="pref_fontScale_title"
android:summary="Override default font scale"
android:inputType="number|numberDecimal"
android:defaultValue="0.0" />
</PreferenceCategory>
</PreferenceScreen>
最后,在SDK中,令人失望的是虽然android.widget.RtlSpacingHelper在属于Android API 33,扩展级别3平台的android.jar中找不到,但是RtlSpacingHelper.java附带平台源。
但真正的问题是有问题的 Fragment 如何影响 Activity 的所有未来行为,是否可能存在规避?