【问题标题】:Android 8.0 Oreo crash on focusing TextInputEditTextAndroid 8.0 Oreo 在聚焦 TextInputEditText 时崩溃
【发布时间】:2018-02-01 02:39:33
【问题描述】:

在将我们的一些设备更新到 android 8.0 后,在关注 TextInputLayout 内的 TextInputEditText 字段时,应用程序会因此 Exception 而崩溃:

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.view.View.getBoundsOnScreen(android.graphics.Rect)' on a null object reference
at android.app.assist.AssistStructure$WindowNode.(AssistStructure.java)
at android.app.assist.AssistStructure.(AssistStructure.java)
at android.app.ActivityThread.handleRequestAssistContextExtras(ActivityThread.java:3035)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1807)
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(Method.java)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

当我们进入 android Settings -> System -> Languages & input -> Advanced -> Auto-fill service -> None ,然后关注TextInputEditText / TextInputLayout不再崩溃。

我们如何在不禁用设备上新的 8.0 自动填充服务的情况下防止崩溃发生?

【问题讨论】:

标签: android android-edittext android-8.0-oreo android-textinputlayout


【解决方案1】:

我也遇到过这个问题,终于找到了android 8.0和android 8.1崩溃的原因。

第一个原因(重要线索):xml中的空提示(android:hint="")导致oreo设备崩溃。请在整个项目搜索中删除editText中的这个空提示。

第二个原因(与上面解释的相同):如果您使用过 TextInputLayout,请确保您的 editText 提示应该显示在 TextInputLayout 中,否则您可以在 editText 中使用提示。

希望对你有帮助!!

谢谢

【讨论】:

    【解决方案2】:

    如果有人仍然想要“TextInputEditText”中的“hint”,请在 TextInputLayout 中制作 app:hintEnabled="false"强>

    <com.google.android.material.textfield.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:hintEnabled="false"
        app:passwordToggleEnabled="true">
    
        <com.google.android.material.textfield.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="password"
            android:inputType="textPassword" />
    
    </com.google.android.material.textfield.TextInputLayout>
    

    【讨论】:

      【解决方案3】:

      @Luke Simpson 是对的。您可以在 theme.XML 中使用它,例如:-

      <item name="editTextStyle">@style/AppEditTextStyle</item>
      
      and then put
      <style name="AppEditTextStyle" parent="Widget.AppCompat.EditText">
              <item name="android:importantForAutofill">auto</item>
       </style>
      

      在 V26/app_styles.xml 中

      但是,我还必须在默认文件夹的 app_styles.xml 中放入空标签。否则,编辑文本的所有属性都会被此覆盖,并且我的编辑文本无法正常工作。 当您为 v26 放置 importantForAutoFill 属性并且希望自动填充在 8.1 中工作时,您可以简单地放置

      <style name="AppEditTextStyle" parent="Widget.AppCompat.EditText">
              <item name="android:importantForAutofill">auto</item>
          </style>
      

      因此,自动填充属性在 8.1 中有效。它将仅在 8.0 中被禁用,因为在 8.0 中发生了崩溃,并且已在 8.1 中修复。

      【讨论】:

        【解决方案4】:

        我也遇到过。事实证明,这个问题是由在嵌套在 TextInputLayout 内的 EditText 上设置提示文本引起的。

        我进行了一些挖掘,并在 26.0.0 Beta 2 发行说明中找到了这个块。 Android Support Release Notes June 2017

        TextInputLayout 必须在 onProvideAutofillStructure() 上设置提示

        这导致我尝试在 TextInputLayout 而不是嵌套的 EditText 上设置提示。

        这为我解决了崩溃问题。示例:

        <android.support.design.widget.TextInputLayout
            android:id="@+id/textInputLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Some Hint Text"
            android.support.design:hintAnimationEnabled="true"
            android.support.design:hintEnabled="true"
            android.support.design:layout_marginTop="16dp">
        
            <android.support.design.widget.TextInputEditText
                android:id="@+id/editText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
        
        </android.support.design.widget.TextInputLayout>
        

        我在混淆书签时将此作为答案发布here。很抱歉两次发布相同的答案。

        【讨论】:

        • 在没有 android.support.design:hintAnimationEnabled 和 android.support.design:hintEnabled 的情况下可以工作吗?我查看了 TextInputLayout 源,加载属性时这两个属性似乎都设置为默认值。
        • @androidguy 是的,它应该在没有这些属性的情况下工作。这些属性告诉 TextInputLayout 在布局中为这些项目分配空间(或者至少这是我观察到的)
        • @Azethoth 此解决方案不保留该行为。就我而言,我将它用于浮动标签动画。当我以这种方式使用它时,提示/标签不会出现。我只能看到一个文本输入
        • @KrishnaCA 这很奇怪。我在我的应用程序中到处使用这种方法,它既在编辑文本中显示提示,又将其动画化为浮动标签。我不确定是什么导致了您的问题。您可以在问题中发布您的 xml 布局的代码示例并将我链接到它吗?我很乐意尝试并提供帮助。
        • 这与您的答案中发布的相同。我测试的设备是华为
        【解决方案5】:

        您可以使用样式或在 XML 中为 importantForAutofill 设置任何值,当您关注 EditText 时它会针对 NPE 进行修复,但如果您长按 EditText 并单击 AutoFill,则无法修复。我发现了一个关于这个错误的错误报告here,请加星并在错误报告中分享你的观察。

        谢谢。

        【讨论】:

          【解决方案6】:

          Luke Simpson 几乎做到了,只是应该使用“styles.xml”而不是“themes.xml”。

          我创建了一个带有版本限定符的新样式文件,针对 v26,使其更清晰。
          只需为 v26/styles.xml 复制并粘贴您的 AppTheme 并将 editTextStyle 项目添加为 EditTextStyle 样式。

          <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
              ...
              <item name="android:editTextStyle">@style/App_EditTextStyle</item>
              <item name="editTextStyle">@style/App_EditTextStyle</item>
          </style>
          
          <style name="App_EditTextStyle" parent="@android:style/Widget.EditText">
              <item name="android:importantForAutofill">noExcludeDescendants</item>
          </style>
          

          通过这种方式,您无需更改布局文件即可对所有您的 EditTexts 进行更改。

          【讨论】:

          • 会注意最低 API 要求,需要放在 v26 资源文件夹中。
          【解决方案7】:

          我使用 v26/themes.xml 来覆盖仅适用于 Oreo 8.0.0 的 EditText 样式自动填充:

          <style name="EditTextStyle" parent="Widget.AppCompat.EditText">
              <item name="android:importantForAutofill">noExcludeDescendants</item>
          </style>
          

          请注意,我必须为布局 xml 中的每个 EditText 应用内联样式才能使其生效。我尝试在我的应用主题中全局应用此更改,但由于某种原因它不起作用。

          // HAD TO DO THIS IN LAYOUT XML FOR EACH EDIT TEXT
          <EditText
              style="@style/EditTextStyle"
              ... />
          
          
          // THIS DIDN'T TAKE EFFECT IN THEMES XML (HAS BEEN ADDED TO MANIFEST)
          <style name="APP_THEME" parent="@style/Theme.AppCompat.Light">
              <item name="android:editTextStyle">@style/EditTextStyle</item>
              <item name="editTextStyle">@style/EditTextStyle</item>
          </style>
          

          【讨论】:

            【解决方案8】:

            在您的EditText 中添加以下提到的属性:

            android:importantForAutofill="noExcludeDescendants"

            【讨论】:

            • 功能仅适用于 API 26 如果您的最小 API 小于 26,是否有解决方案?
            • @JPM 不用担心,它只是在旧 API 级别中被忽略,因此不会崩溃或成为问题。
            • @JPM 问题仅在 Oreo 上,因此对于较旧的 API,它将被忽略并且不会崩溃。
            • 我现在在 PROD 中有它,我的应用程序似乎工作得很好
            • 这是不正确的解决方案。当您长按 EditText 并从菜单中选择自动填充时,它会崩溃。正确(虽然需要代码)解决方案:stackoverflow.com/a/46698028/1714102
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-21
            • 1970-01-01
            • 1970-01-01
            • 2019-02-19
            • 1970-01-01
            相关资源
            最近更新 更多