Play 商店崩溃报告:android.view.View$DeclaredOnClickListener.onClick 上存在 IllegalStateException

2024-01-11

我的一个应用程序收到了一些 IllegalStateException 的崩溃报告。堆栈跟踪表明它来自 android.view.View$DeclaredOnClickListener.onClick(view)。我在测试或日常使用中从未遇到过此错误(我使用app https://play.google.com/store/apps/details?id=com.farmsoft.audiolauncher我自己每天都会使用运行 Android 6.0.1 的三星 Note 4)。老实说,我不知道从哪里开始查看,因为堆栈跟踪似乎甚至没有引用我自己的任何代码,而只是平台代码。我缺少什么?此版本确实使用支持库,但不使用片段,这是此错误的其他解决方案所提到的地方。

下面我粘贴了堆栈跟踪之一。这是来自运行 Android 6.0 的 Moto G Turbo

java.lang.IllegalStateException: 
  at android.view.View$DeclaredOnClickListener.onClick(View.java:4455)
  at android.view.View.performClick(View.java:5201)
  at android.view.View$PerformClick.run(View.java:21163)
  at android.os.Handler.handleCallback(Handler.java:746)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:148)
  at android.app.ActivityThread.main(ActivityThread.java:5443)
  at java.lang.reflect.Method.invoke(Native Method:0)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: java.lang.reflect.InvocationTargetException: 
  at java.lang.reflect.Method.invoke(Native Method:0)
  at android.view.View$DeclaredOnClickListener.onClick(View.java:4450)

抱歉回答太长,但我认为解释如何深入 Android 框架来调试问题很有用。

可以在此处访问引发此异常的代码:

http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/View.java http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/View.java

4452            try {
4453                mMethod.invoke(mHostView.getContext(), v);
4454            } catch (IllegalAccessException e) {
4455                throw new IllegalStateException(
4456                        "Could not execute non-public method for android:onClick", e);
4457            } catch (InvocationTargetException e) {
4458                throw new IllegalStateException(
4459                        "Could not execute method for android:onClick", e);
4460            }

反射及其在点击侦听器中的使用

基本上它所做的是使用反射调用基于字符串的方法。此方法是由应用程序开发人员定义的一种方法,用于响应单击的按钮。这是常见的做法,因为您可以通过 XML 指定 onClickListener 方法,例如您可以调用“goDoWhatever”而不是通常的“onClick”。反射采用此方法的字符串表示形式,并尝试调用该名称的指定类上的方法。

当所需的方法不存在时,例如名称错误、方法是私有的或参数不同,就会发生反射错误。

请注意,在这种情况下,有两种不同的异常,一种针对非公共方法,另一种针对无法执行该方法。我不知道为什么您的堆栈跟踪没有与 IllegalStateException 关联的消息,但制造商可以根据需要修改此代码。

我怀疑您有一个名称正确的方法,因为如果名称错误,解析方法函数会抛出不同的错误:

4463        @NonNull
4464        private Method resolveMethod(@Nullable Context context, @NonNull String name) {
4465            while (context != null) {
4466                try {
4467                    if (!context.isRestricted()) {
4468                        return context.getClass().getMethod(mMethodName, View.class);
4469                    }
                ...
4485            throw new IllegalStateException("Could not find method " + mMethodName
4486                    + "(View) in a parent or ancestor Context for android:onClick "
4487                    + "attribute defined on view " + mHostView.getClass() + idText);
4488        }
4489    }

因此,这给我们留下了我能想到的两种可能性:它找到的方法有错误的签名,或者它找到的方法是静态/私有的。

我将如何调试这个:

我猜您在 xml 中的某处指定了一个点击侦听器(在 xml 文件中查找“android:onClick=”。然后在您的应用程序中搜索同名的所有方法,并确保它们采用单个 View 作为参数(确保您也在文件中导入“android.view.View”,因为导入错误的视图可能会导致这种情况)。还要确保它们不是静态的。可能还值得寻找私有的东西,因为这也可能导致问题但根据你的堆栈跟踪,它似乎不太可能。

为什么这个问题可能难以重现:

如果您注意到 android 框架中的方法“resolveMethod”只是返回同名的第一个方法,那么虽然 java 拥有一个类是有效的:

class Foo{
    void bar(String s){}
    void bar(View s){}

方法签名由名称(例如“bar”)和参数列表(在本例中为包含一项“View”的列表或包含一项“String”的列表)组成。

此 Android 框架代码可能会找到“void bar(String s)”而不是“void bar(View s)”。这可能会导致难以重现的错误,因为反射查找方法的顺序是不确定的(Java反思:类字段和方法的顺序是否标准化? https://stackoverflow.com/questions/1097807/java-reflection-is-the-order-of-class-fields-and-methods-standardized)。因此,您可能很难重现它,因为特定设备可能会以某种方式确定性地迭代它们,但不一定与其他设备/实现相同。

我希望这有帮助!请告诉我结果如何,我是一名研究生,正在研究诸如此类的软件缺陷,因此细节对我来说非常有用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Play 商店崩溃报告:android.view.View$DeclaredOnClickListener.onClick 上存在 IllegalStateException 的相关文章

  • 通知声音不适用于 api 10 android

    我用这个功能来显示状态notification 一切正常 但没有声音播放notification public void notifiction main String ticker String title String text int
  • Android应用主题更换流畅

    我正在开发一个提供白天和夜间主题的项目 我正在更改主题 夜间主题 AppCompatDelegate setDefaultNightMode AppCompatDelegate MODE NIGHT YES 日主题 AppCompatDel
  • 将人类日期(当地时间 GMT)转​​换为日期

    我正在服务器上工作 服务器正在向我发送 GMT 本地日期的日期 例如Fri Jun 22 09 29 29 NPT 2018在字符串格式上 我将其转换为日期 如下所示 SimpleDateFormat simpleDateFormat ne
  • Akka 与现有 java 项目集成的示例

    如果我已经有现有的javaWeb 应用程序使用spring and servlet容器 将 Akka 集成到其中的正确方法是什么 就像我将会有Actor1 and Actor2互相沟通的 开始使用这些演员的切入点是什么 例如 1 把它放在那
  • 提高 PostgreSQL 1 亿数据左连接查询性能

    我在用Postgresql 9 2 version Windows 7 64 bit RAM 6GB 这是一个Java企业项目 我必须在我的页面中显示订单相关信息 有三个表通过左连接连接在一起 Tables TV HD 389772 行 T
  • Android:如何创建模态进度“轮”叠加层?

    我想在我的视图上显示模式进度 轮子 叠加层 ProgressDialog 很接近 但我不想要对话框背景或边框 我尝试设置对话框窗口的背景可绘制 this progressDialog new ProgressDialog Main this
  • 如何在JPanel中设置背景图片

    你好 我使用 JPanel 作为我的框架的容器 然后我真的想在我的面板中使用背景图片 我真的需要帮助 这是我到目前为止的代码 这是更新 请检查这里是我的代码 import java awt import javax swing import
  • Android 为什么这不会抛出错误的线程异常?

    我的印象是视图只能从主线程操作 但是 为什么这不会崩溃 public class MainActivity extends Activity TextView tv Override protected void onCreate Bund
  • 在 Java 中获取并存储子进程的输出

    我正在做一些需要我开始子处理 命令提示符 并在其上执行一些命令的事情 我需要从子进程获取输出并将其存储在文件或字符串中 这是我到目前为止所做的 但它不起作用 public static void main String args try R
  • JDBC 时间戳和日期 GMT 问题

    我有一个 JDBC 日期列 如果我使用 getDate 则会得到 date 仅部分2009 年 10 月 2 日但如果我使用 getTimestamp 我会得到完整的 date 2009 年 10 月 2 日 13 56 78 890 这正
  • 为什么 Google 建议将库复制到您的树中?

    谷歌的Play 服务 API 的使用说明 http developer android com google play services setup html 例如 说 将 extras google google play service
  • hibernate 6.0.2.Final 和 spring boot 2.7.0 的entityManagerFactory bean 未配置问题

    所以最近我想升级我的 Spring Boot 项目项目的一些依赖项 特别是这些组件 雅加达 EE 9 弹簧靴2 7 休眠 6 0 2 Final 完成此操作后 所有更新和代码折射 更新将 javax 导入到 jakarta 以及一些 hib
  • 在android中从SD卡上传图像到facebook

    我无法从 SD 卡上传 Facebook 上的图像 我使用了下面的代码 但它没有给我错误 但同时它没有上传图像 byte data null try FileInputStream fis new FileInputStream filep
  • 将 JavaFX FXML 对象分组在一起

    非常具有描述性和信息性的答案将从我这里获得价值 50 声望的赏金 我正在 JavaFX 中开发一个应用程序 对于视图 我使用 FXML
  • Android:分配内存失败

    我正在尝试创建一个具有 2047 mb 内存的模拟器 当我运行它时 我收到此错误 2011 02 22 14 24 14 Emulator 2011 02 22 14 24 14 Emulator This application has
  • 使用 HtmlUnit 定位弹出窗口

    我正在构建一个登录网站并抓取一些数据的程序 登录表单是一个弹出窗口 所以我需要访问这个www betexplorer com网站 在页面的右上角有一个登录链接 写着 登录 我单击该链接 然后出现登录弹出表单 我能够找到顶部的登录链接 但找不
  • 将 JScrollPane 添加到 JFrame

    我有一个关于向 Java 框架添加组件的问题 我有一个带有两个按钮的 JPanel 和一个添加了 JTable 的 JScrollPane 我想将这两个添加到 JFrame 中 我可以将 JPanel 添加到 JFrame 或将 JScro
  • java'assert'和'if(){}else exit;'之间的区别

    java和java有什么区别assert and if else exit 我可以用吗if else exit代替assert 也许有点谷歌 您应该记住的主要事情是 if else 语句应该用于程序流程控制 而assert 关键字应该仅用于
  • Keystore getEntry 在 Android 9 上返回 NULL

    c我已对存储在 Android 密钥库中的登录密码进行了加密和解密 在 Android 9 上 我观察到应用程序在尝试解密密码时崩溃 我无法重现它 但拥有 Pixel 3 的用户是崩溃的设备之一 下面是我如何从密钥库解密密码 private
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐