java - 非法状态异常 : Could not execute method for android:onClick when trying to migrate to another page?

标签 java android

由于大学实习要求,我一直在开发一个应用程序(根据讲师的推荐,我从另一个学生的最后一年项目中接手了该应用程序),并且在从主菜单屏幕迁移到登录屏幕时遇到了问题。

(只有登录页面有问题,从应用程序的主菜单到注册页面没有任何问题,因此我认为问题可能出在 xml 文件或 LoginActivity.java 中,但不知道如何解决。 )

logcat 错误列出如下:

TAL EXCEPTION: main
Process: com.finchvpn.androidcloudpark, PID: 1579
    java.lang.IllegalStateException: Could not execute method for android:onClick
    at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:389)
    at android.view.View.performClick(View.java:4438)
    at android.view.View$PerformClick.run(View.java:18422)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:136)
    at android.app.ActivityThread.main(ActivityThread.java:5001)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:384)
    at android.view.View.performClick(View.java:4438) 
    at android.view.View$PerformClick.run(View.java:18422) 
    at android.os.Handler.handleCallback(Handler.java:733) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:136) 
    at android.app.ActivityThread.main(ActivityThread.java:5001) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:515) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
    at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.NullPointerException
    at com.finchvpn.androidcloudpark.MainActivity.loginButtonClick(MainActivity.java:74)

以下是相关的xml文件:

主菜单 xml 文件:

<?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"                xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/asd2">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar3"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@drawable/side_nav_bar"
            app:popupTheme="@style/PopupOverlay" />

        <TextView
            android:id="@+id/toolbar_title"
            android:layout_width="239dp"
            android:layout_height="73dp"
            android:layout_gravity="center"
            android:layout_marginBottom="8dp"
            android:text="CloudPark.my"
            android:textColor="@color/md_white_1000"
            android:textSize="14pt"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.11"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.014" />

        <ImageButton
            android:id="@+id/loginButtonPic"
            android:layout_width="132dp"
            android:layout_height="120dp"
            android:layout_gravity="end"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_weight="1"
            android:background="@null"
            android:onClick="loginButtonClick"
            android:scaleType="fitCenter"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.19"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.559"
            app:srcCompat="@drawable/loginnew2"
            tools:ignore="ContentDescription" />

        <ImageButton
            android:id="@+id/RegisterButtonPic"    
            android:layout_width="132dp"
            android:layout_height="120dp"
            android:layout_gravity="end"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_weight="1"
            android:background="@null"
            android:onClick="registerButtonClick"
            android:scaleType="fitCenter"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.813"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.559"
            app:srcCompat="@drawable/registernew1"
            tools:ignore="ContentDescription" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="279dp"
            android:layout_height="63dp"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:text="CloudPark, the next generation parking app."
            android:textColor="@color/md_white_1000"
            android:textSize="10pt"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.505"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.181" />

    </android.support.constraint.ConstraintLayout>

登录xml文件:

<?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/asd2">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar3"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@drawable/side_nav_bar"
            app:popupTheme="@style/PopupOverlay" />

       <TextView
            android:id="@+id/toolbar_title"
            android:layout_width="307dp"
            android:layout_height="91dp"
            android:layout_gravity="center"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="8dp"
            android:text="Login"
            android:textColor="@color/md_white_1000"
            android:textSize="14pt"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.506"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.0" />

       <TextView
            android:id="@+id/textView2"
            android:layout_width="281dp"
            android:layout_height="50dp"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:text="Enter your credentials to access CloudPark."
            android:textColor="@color/md_white_1000"
            android:textSize="10pt"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.505"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.181" />

       <EditText
            android:id="@+id/textUsername"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="8dp"
            android:ems="10"
            android:hint="Username"
            android:inputType="textEmailAddress"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.503"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.352" />

       <EditText
            android:id="@+id/textPassword"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:ems="10"
            android:hint="Password"
            android:inputType="textPassword"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.503"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.443" />

      <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="8dp"
            android:background="#0026FF"
            android:onClick="loginButtonClick"
            android:text="Login to CloudPark"
            android:textColor="#FFFF"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.687" />

      <android.support.constraint.Guideline
            android:id="@+id/guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_begin="20dp" />

  </android.support.constraint.ConstraintLayout>

LoginActivity.java

public class LoginActivity extends AppCompatActivity {

    private EditText textUsername;
    private EditText txtPassword;
    private static RestClient restClient = new RestClient();

    private SharedPreferences.Editor sharedPreferencesEditor;

    @SuppressLint("CommitPrefEdits")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        try {
            Toolbar toolbar = findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);

            Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setDisplayShowHomeEnabled(true);
        } catch (Exception e) {
        }

        textUsername = findViewById(R.id.textUsername);
        txtPassword = findViewById(R.id.textPassword);
        SharedPreferences sharedPreferences = getSharedPreferences("UserInfo", 0);
        sharedPreferencesEditor = sharedPreferences.edit();
            textUsername.setText(sharedPreferences.getString("textUsername", ""));
            txtPassword.setText(sharedPreferences.getString("txtPassword", ""));
    }

    public static RestClient getRestClient() {
        return restClient;
    }

    public void loginButtonClick(View v) {
        if (!textUsername.getText().toString().equals("") && !txtPassword.getText().toString().equals("")) {
            apiPostLogin(Constants.ANDROID_KEY + ":" + textUsername.getText().toString() + ":" + txtPassword.getText().toString());
            sharedPreferencesEditor.putString("textUsername", textUsername.getText().toString());
            sharedPreferencesEditor.putString("txtPassword", txtPassword.getText().toString());
            sharedPreferencesEditor.commit();
        } else {
            Toast.makeText(LoginActivity.this, "NULL", Toast.LENGTH_LONG).show();
        }
    }

    private void apiPostLogin(String data) {
        final ProgressDialog progress = new ProgressDialog(this);
        progress.setTitle("Logging in");
        progress.setMessage("Please wait ...");
        progress.setCancelable(false); // disable dismiss by tapping outside of the dialog
        progress.show();
        Call<ResponseBody> call = getRestClient().getLoginService().postLogin(data);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if (response.isSuccessful() && response.body() != null) {
                    try {
                        String data = response.body().string();
                        JSONObject jsonObject = new JSONObject(data);
                        Constants.uid = Integer.parseInt(jsonObject.getString("id"));
                        Constants.username = jsonObject.getString("username");
                        Constants.email = jsonObject.getString("email");
                        Constants.credit = jsonObject.getString("credit");
                        Constants.qr_code = jsonObject.getString("qr_code");
                        Constants.created_at = jsonObject.getString("created_at");
                        Constants.updated_at = jsonObject.getString("updated_at");
                        Toast.makeText(LoginActivity.this, "apiPostLogin onResponse <<<< \r\n\r\n" + jsonObject.toString(), Toast.LENGTH_LONG).show();
                        Intent returnIntent = new Intent();
                        setResult(Activity.RESULT_CANCELED, returnIntent);
                        finish();
                    } catch (IOException | JSONException e) {
                        e.printStackTrace();
                    }
                }
                progress.dismiss();
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Toast.makeText(LoginActivity.this, "Incorrect username/password, please try again." + t.getMessage(), Toast.LENGTH_LONG).show();
                progress.dismiss();
            }
        });
    }
}

最佳答案

我怀疑该问题与主菜单 xml 和登录 xml 中的 android:onClick="loginButtonClick" 冲突有关。

您不应依赖 android:onClick 属性来处理 View 点击。这是因为在使用 android:onClick 时,您无法确定处理 onClick 的方法是否有效。没有确切的机制来确保您的代码连接到 View 。另一个问题是,android:onClick 不适用于 Fragment。因此,我认为使用 android:onClick 是不好的做法。

要解决此问题,请在 View 上使用 setOnClickListener。与 findViewById 结合使用,您的代码将更加健壮,因为如果您为 findViewById 提供了不正确的 ID,您总是会看到错误。为了使您的代码更加健壮并避免 id 冲突,您需要为 View 使用描述性名称 id。使用这样的命名约定:

layout name + _ + What the view for + _ + type of view

例如,对于您的登录 xml,您可以使用如下内容:

....

<Button
    android:id="@+id/login_cloudpark_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginTop="8dp"
    android:background="#0026FF"
    android:text="Login to CloudPark"
    android:textColor="#FFFF"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.687" />

<android.support.constraint.Guideline
    android:id="@+id/login_begin_gdl"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_begin="20dp" />

...

然后将其与 findViewById 一起使用:

public class LoginActivity extends AppCompatActivity {

  ...

  private Button mBtnLogin;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);

    ...

    mBtnLogin = findViewById(R.id.login_cloudpark_btn);
  }
}

之后,将 clickListener 添加到 mBtnLogin:

mbtnLogin.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
         // place your clicking handle code here.
      }
    });

通过执行上述操作,您将干净地分离 xml 中的 View 和逻辑。

关于java - 非法状态异常 : Could not execute method for android:onClick when trying to migrate to another page?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50293776/

相关文章:

Android NDK - 附加包含目录

java - JNI 函数是否可能返回整数或 boolean 值?

android - Volley ,不在 JsonArrayRequest 中传递任何参数

java - 为什么 Spring Boot MVC 总是从我的表单返回 null 值?

java - mysql 5.5 无效的转义序列 java

java - SLF4J 的 “dynamic binding” 功能什么时候适合使用?

android - 在多个国家/地区使用 Android 应用程序的一种翻译

java - 如何使用mockito抛出JsonProcessingException

java - 在我的 Map-Reduce 作业中包含第三方库(使用分布式缓存)

android - 如何确定 TextView 中可见的行数?