You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

仅三星S6 Edge安卓7版本触摸TextView触发空指针崩溃

问题复现与现象
  • 复现设备范围:仅搭载Android 7系统的三星Galaxy S6 Edge,其余设备无同类异常
  • 触发路径:用户触摸文本类控件(TextView、EditText、Button等)时直接触发致命崩溃
  • 崩溃异常:java.lang.NullPointerException
  • 核心报错信息:尝试在空对象引用上调用虚方法 boolean android.widget.Editor$SelectionModifierCursorController.isDragAcceleratorActive()
完整崩溃堆栈
Fatal Exception: java.lang.NullPointerException: Attempt to invoke
virtual method 'boolean
android.widget.Editor$SelectionModifierCursorController.isDragAcceleratorActive()'
on a null object reference
at android.widget.Editor.updateFloatingToolbarVisibility(Editor.java:1541)
at android.widget.Editor.onTouchEvent(Editor.java:1491)
at android.widget.TextView.onTouchEvent(TextView.java:10012)
at android.view.View.dispatchTouchEvent(View.java:10717)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.widget.ScrollView.dispatchTouchEvent(ScrollView.java:738)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2550)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:559)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1870)
at android.app.Activity.dispatchTouchEvent(Activity.java:3236)
at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:521)
at android.view.View.dispatchPointerEvent(View.java:10946)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5110)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4962)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4493)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4546)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4512)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4645)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4520)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4702)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4493)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4546)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4512)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4520)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4493)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7000)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6929)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6890)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7110)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(InputEventReceiver.java)
at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176)
at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:7074)
at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:7137)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:927)
at android.view.Choreographer.doCallbacks(Choreographer.java:702)
at android.view.Choreographer.doFrame(Choreographer.java:632)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:913)
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:6682)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
问题根因

该问题属于三星定制Android 7系统的ROM原生缺陷:三星修改了系统android.widget.Editor类的updateFloatingToolbarVisibility方法逻辑,未对SelectionModifierCursorController实例做空值判断就直接调用其isDragAcceleratorActive()方法。当文本控件未完成编辑器初始化、或未启用文本选择功能时被触摸,就会触发该空指针崩溃,不属于应用自身代码逻辑错误。

修复方案
  • 通用兼容方案:自定义所有文本类控件(包括TextView、EditText、Button、CheckedTextView等),重写onTouchEvent方法捕获该特定空指针异常,避免崩溃,示例代码如下:
public class FixBugTextView extends AppCompatTextView {
    // 实现类的三个构造方法
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        try {
            return super.onTouchEvent(event);
        } catch (NullPointerException e) {
            // 拦截三星Android7系统Editor模块空指针崩溃
            return true;
        }
    }
}
  • 轻量方案:针对三星Android 7设备,对不需要文本选择功能的控件主动调用setTextIsSelectable(false),跳过选择工具栏更新逻辑,从触发路径上规避问题。
  • 依赖升级方案:如果项目使用AndroidX的AppCompat控件库,将androidx.appcompat:appcompat升级到1.2.0及以上版本,官方已对该类厂商ROM空指针异常做了内置兼容拦截。

内容的提问来源于stack exchange,提问作者Anwar Zahid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 11:33:20