按钮 onClick 强制关闭 Android 4.1 设备上的应用程序

Buttons onClick Force closes app on Android 4.1 device

我的应用程序布局简单,只有一个按钮。我尝试使用 AppCompatButtonAppCompatImageButton 实现 onClick。但是当我 运行 它在 Android 4.1 设备上时,当我点击它时,我的应用程序崩溃了(不幸的是,应用程序已停止)。

我在 Android 5.0 设备上进行了相同的测试,并且成功了。然后尝试相同但使用 ButtonImageButton 代替并且它适用于两者。

这些按钮没有应用任何样式或主题。只有 30 x 30 dp 的裸按钮。这是代码:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat
xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        app:titleTextColor="@color/white" />

    <androidx.appcompat.widget.LinearLayoutCompat
        android:id="@+id/adContainer"
        android:layout_width="match_parent"
        android:layout_height="90dp">

        <androidx.appcompat.widget.AppCompatButton
            android:id="@+id/btn"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:onClick="btnClick" />

    </androidx.appcompat.widget.LinearLayoutCompat>

</androidx.appcompat.widget.LinearLayoutCompat>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Set ActionBar to Toolbar
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

    }


    public void btnClick(View v) {
        // DO SOMETHING
    }
}

目前我正在使用 ImageButton 但我不知道这是否意味着某些 Android 版本存在兼容性问题(我支持 API 16+ ).

谢谢。

编辑: 这就是 LogCat 使用 AppCompatButton 时显示的内容:

10-03 17:01:36.706 1313-1313/com.example.testappcompatbutton D/AndroidRuntime: Shutting down VM
10-03 17:01:36.706 1313-1313/com.example.testappcompatbutton W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0xa62ba288)

    --------- beginning of /dev/log/system
10-03 17:01:36.734 1313-1313/com.example.testappcompatbutton E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.IllegalStateException: Could not find a method btnClick(View) in the activity class androidx.appcompat.widget.TintContextWrapper for onClick handler on view class androidx.appcompat.widget.AppCompatButton with id 'btn'
        at android.view.View.onClick(View.java:3578)
        at android.view.View.performClick(View.java:4084)
        at android.view.View$PerformClick.run(View.java:16966)
        at android.os.Handler.handleCallback(Handler.java:615)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NoSuchMethodException: btnClick [class android.view.View]
        at java.lang.Class.getConstructorOrMethod(Class.java:460)
        at java.lang.Class.getMethod(Class.java:915)
        at android.view.View.onClick(View.java:3571)
        at android.view.View.performClick(View.java:4084) 
        at android.view.View$PerformClick.run(View.java:16966) 
        at android.os.Handler.handleCallback(Handler.java:615) 
        at android.os.Handler.dispatchMessage(Handler.java:92) 
        at android.os.Looper.loop(Looper.java:137) 
        at android.app.ActivityThread.main(ActivityThread.java:4745) 
        at java.lang.reflect.Method.invokeNative(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:511) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
        at dalvik.system.NativeStart.main(Native Method) 

好像找不到onClick方法

我以前从未真正见过这个,但它看起来像是两件事的结合:

  • 在棒棒糖之前的设备上,AppCompatButton 使用 TintContextWrapper 作为按钮视图的上下文
  • android:onClick 属性使用反射来查找要执行的方法,查看视图的上下文

一起,这意味着系统在错误的地方寻找 btnClick(),因此应用程序崩溃了。

您可以通过代码设置点击侦听器来解决此问题,而不是使用 android:onClick 属性。在您的 MainActivity 的 onCreate() 方法中:

View button = findViewById(R.id.btn);
button.setOnClickListener(v -> btnClick(v));