Не удалось найти метод onClick_Foo (View) - первый раз на Android Lollipop

У меня есть приложение, которое около года, находится в Play-магазине в бета-версии, прошло десятки изменений. Внезапно я получаю сообщение об ошибке:

Не удалось найти метод onClick_Foo (View) в классе активности android.view.ContextThemeWrapper для обработчика onClick в классе просмотра android.widget.Button с id 'Foo_Button'

Я получаю эту ошибку на каждой из 7 кнопок, определенных в моем XML. Со вчерашнего дня я обновляю appcompat-v7 с 21.0.3 до 22.0.0, но также впервые обновил свое тестовое устройство от KitKat до Lollipop.

Я дважды проверял записи, заглавные буквы, ни один из обычных подозреваемых не объясняет это. Вот пример соответствующего кода. Дайте мне знать, если вы почувствуете, что больше будет полезно. (В действии есть 915 строк кода и xml 186, поэтому не просите все это). Тестирование на Verizon Note 4 работает Lollipop 5.0.1

activity_pick.xml:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:theme="@style/AppTheme"
    tools:context="com.myapp.Pick"
    android:layout_height="match_parent"
    android:layout_width="match_parent">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:orientation="vertical">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/Ratings_Button"
            android:textSize="16dp"
            android:text="@string/Pick_Ratings_Button"
            android:onClick="onClick_Ratings"
            android:background="@android:drawable/btn_default"/>
</LinearLayout>
</ScrollView>

Pick.java:

public class Pick_Restaurant extends ActionBarActivity {
    public void onClick_Ratings (View v) {
        Intent intent = new Intent(mContext, Ratings.class);
        startActivityForResult(intent,RATINGS);
    }
}

build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

defaultConfig {
    minSdkVersion 15
    targetSdkVersion 22
    versionCode 59
    versionName "0.6.4"
}

...

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:22.0.0'
    compile 'com.google.android.gms:play-services:7.0.0'
    compile files('libs/mobileservices-1.1.5.jar')
}

Полная ошибка в журнале:

04-08 17:06:40.578    3508-3508/com.myapp.debug E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.myapp.debug, PID: 3508
    java.lang.IllegalStateException: Could not find a method onClick_Ratings(View) in the activity class android.view.ContextThemeWrapper for onClick handler on view class android.widget.Button with id 'Ratings_Button'
            at android.view.View$1.onClick(View.java:4234)
            at android.view.View.performClick(View.java:5191)
            at android.view.View$PerformClick.run(View.java:20916)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:145)
            at android.app.ActivityThread.main(ActivityThread.java:5974)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
     Caused by: java.lang.NoSuchMethodException: onClick_Ratings [class android.view.View]
            at java.lang.Class.getMethod(Class.java:665)
            at android.view.View$1.onClick(View.java:4227)
            at android.view.View.performClick(View.java:5191)
            at android.view.View$PerformClick.run(View.java:20916)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:145)
            at android.app.ActivityThread.main(ActivityThread.java:5974)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)

Ответы

Ответ 1

Похоже, это новая проблема с Android 5.0.

От этот anwer, удалив Theme из макета xml, исправил эту проблему для них.

Итак, в вашем случае удалите Theme из вашего макета:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <!--android:theme="@style/AppTheme"--> <!-- Remove this -->
    <!--................-->
  </ScrollView>

И добавьте тему в AndroidManifest.xml вместо:

android:theme="@android:style/AppTheme"

Ответ 2

Я только что ответил на аналогичный вопрос здесь

В принципе, поскольку Android 5.0 отдельные виды могут быть тематическими.

Чтобы облегчить это, ContextThemeWrapper используется для изменения основной темы, назначенной Activity и назначенной как Context для View. Поскольку этот Context больше не является вашим Activity (Activity должен быть отдельным, поскольку он все равно должен возвращать исходную тему), обратные вызовы не существуют, и вы получаете сообщение об ошибке.

Если вы действительно не хотите обсуждать отдельные взгляды, очевидное решение состоит в том, чтобы не делать этого и вместо этого использовать тему, как уже было предложено.

Если вы действительно хотите использовать отдельные представления, кажется, что атрибут android:onClick не может быть использован, и вам придется отступить, чтобы вручную назначить OnClickListener.

Вопрос в том, почему это работало до Lollipop? Я могу только предположить, что, поскольку функциональность для отдельных индивидуальных представлений не существовала, применение атрибута theme к представлению просто изменило бы тему по умолчанию на Activity.

Ответ 3

Такие вещи обычно случаются, когда вы объявляете onClick в xml, как и вы:

android:onClick="onClick_Ratings"

Просто убедитесь, что вы используете этот макет в этом действии. Поскольку исключение явно говорит о том, что у вашей деятельности нет соответствующего метода, который вы показали, у вас есть:

public void onClick_Ratings (View v) {
    Intent intent = new Intent(mContext, Ratings.class);
    startActivityForResult(intent,RATINGS);
}

Также я предполагаю, что вы должны объявить активность в вашем xml, например:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".SendMessageActivity">

И на самом деле журнал говорит:

Не удалось найти метод onClick_Ratings (View) в классе активности android.view.ContextThemeWrapper

что-то не так, поскольку android.view.ContextThemeWrapper не является Activity, а не активностью вашего xml com.myapp.Pick (я предполагаю, что Pick - это действие, а не фрагмент). Возможно, попробуйте очистить проект, ивалифицировать кеши и перезагрузить.
Если ничего не помогает, я предлагаю вам вернуться к предыдущей версии поддержки lib, о которой вы упоминали OR, чтобы установить onClickListener в коде вместо xml.

Ответ 4

Удаление андроида: тема работает. Но это вызвано тем, что используется android:onclick в xml. Если вы используете onClick в файле Java, вы все равно можете использовать андроид: тема.

В соответствии с вашим кодом

activity_pick.xml [Удалить onclick здесь]

 <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/Ratings_Button"
        android:textSize="16dp"
        android:text="@string/Pick_Ratings_Button"        
        android:background="@android:drawable/btn_default" />

Перейдите в свой файл Java, то есть pick.java в вашем случае:

    final Button button = (Button) findViewById(R.id.Ratings_Button);

    button.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            Intent activityChangeIntent = new Intent(CurrentActivity.this, SecondActivity.class);
            SplashScreen.this.startActivity(activityChangeIntent);
        }
    });

Опытная та же ошибка, приложение перестало работать, когда программная кнопка нажала программно, помогла мне. Проверьте это:)